1

Git can track the mode of files (like 755 or 644). I did a global update of chmod of all my working files but only some of them had a bad chmod. Now I have a mix of updated files : some with new code I updated before and others with only a new mode. How can I add to Git only files that have a new mode?

In the Git documentation I have found a chmod option but I'm not sure if it useful in my case.

joanis
  • 10,635
  • 14
  • 30
  • 40
Klemart3D
  • 180
  • 9
  • You could try to use `--chmod=+x` https://stackoverflow.com/questions/40978921/how-to-add-chmod-permissions-to-file-in-git – pixeloverflow Jul 15 '19 at 14:07
  • What does `git status` show? – wjandrea Jul 15 '19 at 14:47
  • It sounds like you could just `stash`, run the mode change command(s) again, commit, then pop the stash. – wjandrea Jul 15 '19 at 14:47
  • @wjandrea `git status` showing me a mix of modified files: code and chmod. My question is how to add only chmod modified files for the next commit. A `git stash` would have been great before my chmod update but now it's too late, all files are mixed together, so may be it exists a reverse solution: git stash only code modified files? – Klemart3D Jul 16 '19 at 08:18
  • @Klemart3D How is it too late? I'm saying stash, do the mode change again, commit, pop the stash. – wjandrea Jul 16 '19 at 11:47

2 Answers2

1

You could change the mode of all your files, and do a git add . Since git tracks only what's changed, it will only add those files whose mode has changed.

Note that this works on filesystems that correctly track the executable bit (the only mode tracked by git). On windows you might need to use the --chmod option you linked.

A. M.
  • 384
  • 1
  • 6
  • A `git add .` adding all modified files: code like chmod. I just want to add for next commit files with a new chmod (not code files modified before the chmod update). – Klemart3D Jul 16 '19 at 08:34
  • check @wjandrea comment on your question. You could always stash your non-mode modifications and pop them back after the mode change commit. I'm hoping you don't have so many modified files that makes manual stashing them unfeasible. – A. M. Jul 16 '19 at 08:44
  • I have so many modified files an I can't visually differentiate (with a `git status`) files code modified from files chmod modified (and may some files have a code + chmod modifications too), that's why I'm asking if an automated solution exists :) – Klemart3D Jul 16 '19 at 08:59
0

The easy answer, except on some Windows systems, is just to use git add . from the top level of the work-tree, or git add -u. Re-adding an already added file is harmless; re-adding an existing file also picks up its new mode setting.

More about the index / staging-area

As an exercise, run the command:

git ls-files --stage

on an existing repository that has a bunch of files checked out. (This prints a lot of output in a big repository, and does not use a pager by default, so you might want to add | page or | less or whatever you do for paging.)

The result of this listing tells you all the files that will be in the next commit you make. If you run git commit right after this git ls-files command, you'll get a new commit containing exactly the set of files listed by git ls-files, with the mode information being that shown by --stage (as the first column).

Compare the output to that from git status:

$ git ls-files --stage | wc -l
    3606

There are more than three thousand six hundred files staged for commit! But:

$ git status
On branch master
Your branch is up to date with 'origin/master'.

nothing to commit, working tree clean

Why are these different? Why does git status report that there is nothing staged, when git ls-files reports 3606 staged files?

The answer is that the current commit—the tip of master—has the same 3606 files:

$ git ls-tree -r HEAD | wc -l
    3606

Moreover, the 3606 files in the HEAD commit are the same—mode, size, and bytes-of-data—as the 3606 files in the index / staging-area. So git status, which compares these two, says that none of them are different and there is nothing to commit.

If you change one file in the index / staging-area—by changing the copy that's in the work-tree, or even by just changing the mode—there will still be 3606 files in the staging area, but this time, one will be different. The git ls-files command will list all 3606; the git status command will list the different files. Which of these is more useful in every-day work?

The index / staging-area holds a copy of every file, ready to go into the next commit. This is where the mode—always 100755 or 100644—comes from, too. Whatever is in the index / staging-area, that's what gets committed when you run git commit. The reason you have to run git add is to tell Git: Update the index copy from the work-tree copy.

torek
  • 448,244
  • 59
  • 642
  • 775