3

I want to modify the index of one (text) file without having to change the working tree file state. Is this possible?

Mot
  • 28,248
  • 23
  • 84
  • 121

3 Answers3

1

yes, you can use the --work-tree option on the git level of any (this is not actually true. It should work on any but there are edge cases) command:

git show HEAD:path/to/your/file.txt > /some/other/place/file.txt
# modify the file in /some/other/place/file.txt
git --work-tree=/some/other/place add /some/other/place/file.txt
user229044
  • 232,980
  • 40
  • 330
  • 338
Adam Dymitruk
  • 124,556
  • 26
  • 146
  • 141
  • What does the second Git command with the `--work-tree` option exactly does? What Git version is required? Should the provided path always be the parent directory of the added file? – Mot Dec 20 '11 at 20:32
  • the `--work-tree` option tells the git command to execute with the alternate directory provided as the working directory. This allows you to leave your working directory unaffected. This should be available on all Git versions unless you have something really old. Work-tree option was introduced in June, 2007. The directory can be anything you like but usually would be outside of the current working tree. Why do you require the file in the working directory to not be changed? – Adam Dymitruk Dec 20 '11 at 20:42
  • 1
    @AdamDymitruk I suspect you're using "working directory" to mean something other than what it normally means. Normally, "working directory" means the thing printed by `pwd` and modified by `cd`. What do you mean in this case? – Laurence Gonsalves Dec 22 '11 at 23:49
  • In this case, for the duration of the git command, treat the given directory as the working folder for the current repo. – Adam Dymitruk Dec 23 '11 at 18:59
1

Yes, you can explicitly stage a blob at a particular path with git update-index.

git update-index --cacheinfo 100644 <sha1-of-blob> path/in/repo

You will also need to use --add if the path is a branch new file.

If the file that you want to stage is a blob that doesn't yet exist in the git repository then you can store a new blob in the git repository with git hash-object, e.g.:

blobid=$(command_that_creates_output | git hash-object -w --stdin)

or

blobid=$(git hash-object -w /path/not/necessarily/in/repository)

You can then stage the blob as above.

git update-index --cacheinfo 100644 blobid path/in/repo
CB Bailey
  • 755,051
  • 104
  • 632
  • 656
  • The file content to stage would be from a temporary (hence unversioned) file (if necessary: from within the working tree). – Mot Dec 21 '11 at 18:45
  • @MikeL: That's fine to, when I said "path/outside/repository" I really meant "not necessarily in the repository". – CB Bailey Dec 21 '11 at 22:54
1

Another take on "changing file in index without altering working dir" is to apply a patch to index only. This is often the way GUI git clients stage only selected lines from a given file.

You start out by (if you want) clearing out the changes from index for that file:

git reset path/to/file

Then extracting the full patch for it

git diff path/to/file > /path/to/tmpfile

Edit the patch file to include only the changes you want to apply, and apply just the edited patch:

git apply --cached /path/to/tmpfile

See:

git help apply
ddotsenko
  • 4,926
  • 25
  • 24