Skip to content
This repository was archived by the owner on Sep 11, 2020. It is now read-only.

Unix executables changed to regular files upon clone in Windows #373

Closed
osklyar opened this issue May 3, 2017 · 2 comments
Closed

Unix executables changed to regular files upon clone in Windows #373

osklyar opened this issue May 3, 2017 · 2 comments
Labels

Comments

@osklyar
Copy link

osklyar commented May 3, 2017

A Windows clone of a repository that contains Unix executables results in executable file permission change in the change set to regular directly upon clone. I guess the reason lies somewhere in func (w *Worktree) checkoutChangeRegularFile(...) error due to the fact that filemode.NewFromOSFileMode(fi.Mode()) in func (w *Worktree) addIndexFromFile(name string, h plumbing.Hash, idx *index.Index) error delivers on Windows regular for anything that is actually executable on Unix.

Version used: master

Here is the behaviour that I observed. First, here is a clone with the default git client. The clone causes no file permission change:

D:\Downloads>git.exe clone git@gitserver:xentis/java std-client
Cloning into 'std-client'...
remote: Counting objects: 36, done.
remote: Compressing objects: 100% (33/33), done.
remote: Total 36 (delta 8), reused 0 (delta 0)
Receiving objects: 100% (36/36), 64.00 KiB | 0 bytes/s, done.
Resolving deltas: 100% (8/8), done.

D:\Downloads>cd std-client

D:\Downloads\std-client>git status
On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working tree clean

Next, the same clone with the following go-git code:

repo, err := git.PlainClone(dir, false, &git.CloneOptions{
  RemoteName: remote,
  URL:        url,
  Auth:       auth,
})

Triggers permission change upon clone:

D:\Downloads>gitc.exe clone git@gitserver:xentis/java go-git-client
�[K⠸ cloning...

And checking the status with the default git client:

D:\Downloads>cd go-git-client

D:\Downloads\go-git-client>git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    modified:   gradlew
    modified:   populate.sh

Now checking what are the differences:

D:\Downloads\go-git-client>git reset HEAD .
Unstaged changes after reset:
M       gradlew
M       populate.sh

D:\Downloads\go-git-client>git diff
diff --git a/gradlew b/gradlew
old mode 100755
new mode 100644
diff --git a/populate.sh b/populate.sh
old mode 100755
new mode 100644
@osklyar osklyar changed the title Clone on Windows changes file permissions upon clone (different behaviour from standard client) Unix executables changed to regular files upon clone in Windows May 3, 2017
@osklyar
Copy link
Author

osklyar commented May 4, 2017

What is more, actually the executable status of those files on the filesystem is set correctly (using Git Bash for Windows this is what I get):

SKOL@PDNB142 MINGW64 /d/Downloads
$ ./gitc clone git@gitserver:xentis/java go-git-client

SKOL@PDNB142 MINGW64 /d/Downloads
$ cd go-git-client/

SKOL@PDNB142 MINGW64 /d/Downloads/go-git-client (master)
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        modified:   gradlew
        modified:   populate.sh


SKOL@PDNB142 MINGW64 /d/Downloads/go-git-client (master)
$ ls -la
total 51
drwxr-xr-x 1 SKOL 1049089    0 May  4 14:58 ./
drwxr-xr-x 1 SKOL 1049089    0 May  4 14:58 ../
-rw-r--r-- 1 SKOL 1049089  112 May  4 14:58 .editorconfig
drwxr-xr-x 1 SKOL 1049089    0 May  4 14:58 .git/
-rw-r--r-- 1 SKOL 1049089  201 May  4 14:58 .gitignore
-rw-r--r-- 1 SKOL 1049089 2605 May  4 14:58 build.gradle
drwxr-xr-x 1 SKOL 1049089    0 May  4 14:58 gradle/
-rwxr-xr-x 1 SKOL 1049089 5299 May  4 14:58 gradlew*
-rw-r--r-- 1 SKOL 1049089 2260 May  4 14:58 gradlew.bat
drwxr-xr-x 1 SKOL 1049089    0 May  4 14:58 platform/
-rwxr-xr-x 1 SKOL 1049089  161 May  4 14:58 populate.sh*
-rw-r--r-- 1 SKOL 1049089 4046 May  4 14:58 settings.gradle
-rw-r--r-- 1 SKOL 1049089  914 May  4 14:58 setup-ide-integration.gradle
-rw-r--r-- 1 SKOL 1049089 4635 May  4 14:58 versions.gradle

SKOL@PDNB142 MINGW64 /d/Downloads/go-git-client (master)
$ git reset HEAD .
Unstaged changes after reset:
M       gradlew
M       populate.sh

SKOL@PDNB142 MINGW64 /d/Downloads/go-git-client (master)
$ git checkout -- .

SKOL@PDNB142 MINGW64 /d/Downloads/go-git-client (master)
$ ls -la
total 51
drwxr-xr-x 1 SKOL 1049089    0 May  4 14:59 ./
drwxr-xr-x 1 SKOL 1049089    0 May  4 14:58 ../
-rw-r--r-- 1 SKOL 1049089  112 May  4 14:58 .editorconfig
drwxr-xr-x 1 SKOL 1049089    0 May  4 14:59 .git/
-rw-r--r-- 1 SKOL 1049089  201 May  4 14:58 .gitignore
-rw-r--r-- 1 SKOL 1049089 2605 May  4 14:58 build.gradle
drwxr-xr-x 1 SKOL 1049089    0 May  4 14:58 gradle/
-rwxr-xr-x 1 SKOL 1049089 5299 May  4 14:59 gradlew*
-rw-r--r-- 1 SKOL 1049089 2260 May  4 14:58 gradlew.bat
drwxr-xr-x 1 SKOL 1049089    0 May  4 14:58 platform/
-rwxr-xr-x 1 SKOL 1049089  161 May  4 14:59 populate.sh*
-rw-r--r-- 1 SKOL 1049089 4046 May  4 14:58 settings.gradle
-rw-r--r-- 1 SKOL 1049089  914 May  4 14:58 setup-ide-integration.gradle
-rw-r--r-- 1 SKOL 1049089 4635 May  4 14:58 versions.gradle

As you see there is executable permission on gradlew and populate.sh right after clone and there is no permission change after the reset of the changeset. So it must be matching the index to the file system that is not running correctly.

By adding a small Windows specific workaround to func (w *Worktree) addIndexFromFile(name string, h plumbing.Hash, idx *index.Index) error I have managed to keep those "changes" unstaged, but am surprised why I am still getting them. The workaround would be to pass the TreeEntry of the original index into the method and if we are in windows and the file systems tells us that the file is regular, while the index thinks it is executable, keep the mode from the tree.

@osklyar
Copy link
Author

osklyar commented May 5, 2017

Closing in favour of #378

@osklyar osklyar closed this as completed May 5, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

2 participants