Home > Back-end >  Command-line way to commit all but one chunk of a file in GIT?
Command-line way to commit all but one chunk of a file in GIT?

Time:05-31

For a personal project, I started on code changes, then realized I needed something more complex, so I didn't commit them and did other things.

Two hours later I had an idea to make a big sweeping change. In this case, it was replacing the word "touchable" with "fungible" in Inform 7, to speed things up. So I made the change quickly, not stashing the current code. (Yes, this is an error in process. But it's one that will happen again.)

The problem was, there were 250 chunks in one file that the text was changed and only one or two chunks related to the changes I'd started working on. And I wanted to commit the 250 without the 2.

This wasn't painful once I tracked the line numbers (9100 to 9200) and used git add --patch story.ni to verify changes until the critical sector. I typed y quickly until I got to line 8800. Then I slowed down and typed a to add the rest.

I suppose I could also have cut the file down to 9100 lines, added, undid the truncation, and type n then a. But I'm not looking for tricks. I'm looking to become more confident with the inner workings of git, e.g. if there are command line arguments that would clean this up e.g.

git add --linechunk:1-9100 --linechunk:9200-30000

Or...

git add --linechunk:-9100 --linechunk:9200

Though my method was good enough, knowing if there's a way to do more than manually patch things would be neat.

For those more agile with git, is there a way to do be more efficient?

CodePudding user response:

The simplest approach here would have been to use git diff to make a patch file, edit it, and apply it.

In other words, you'd effectively be doing a git add --patch but not interactively, thus avoiding the tedium of waiting for your special line to come round.

Example:

% git diff > ~/Desktop/mypatch.txt
# edit the patch file in your favorite editor, 
# undoing the part you don't want changed
# don't forget to save!
% git apply --cached -- ~/Desktop/mypatch.txt
% git commit

Edit: It is pointed out in a comment by @root that git add --edit (or simply git add -e) does the same thing more compactly. This is true, so it deserves a mention. I like the luxury of working on my own patch file in my own time, but if you don't mind working on the patch while Git waits for you to close the editor, this can be a simpler alternative.

CodePudding user response:

git add -p is a handy tool to know on reduced changesets, IMHO you are expecting a bit too much out of it in your situation.
One should keep in mind that the target result is simply to be able to place the version you want for a file in the index.


Here are a few other ways to reach that result :

  • run git gui, add the complete file in the staging area, then scroll through the staged file to unstage just the two chunks you are looking for (from my experience : although its interface looks clunky, git gui is a very useful tool to review and edit your changes before committing, and has a "add this line/remove this line" which works in all situations)

  • rename that file to filename.tmp, run git checkout filename, apply search and replace, add and commit, then restore your initial file (mv filename.tmp filename)

  • stash your current changes, reapply the "search replace", commit that file, run git stash pop (from your description, it looks like there shouldn't even be a conflict, but if there is the way to fix that is probably to take the version from the stash)

  • undo your search & replace (either you still have it in your ctrl Z stack, or just replace the other way around), commit or stash that version of the file, then reapply your search & replace, and commit that new version (you now have two commits, you can rebase/cherry-pick ... )

  • etc ...

CodePudding user response:

As an almost-comment since Matt's answer is probably best in general for a case this extreme, but git reset also has a --patch option (as does git checkout), so you can easily clean up goofs.

Also: any decent programmer's editor will have a Git plugin that can stage and unstage hunks directly from the edit buffer, so even easier would be to add the whole thing and unstage the bits you didn't mean that way. git gui can do that for people whose editors can't manage that.

  • Related