Reputation: 1421
this happens quite often to me:
After a day of coding i start to stage relevant changes for a feature. I do this mostly by "git add -p" to selectively add only relevant changes (keep debug things and so on out).
But then i realize that i also did something which is also worth to be committed. Its not related to the feature, but affects same code. Therefore i want to commit this before. Unfortunately i already spend a lot of time for staging the feature. How do you handle this situation?
My current solution is this:
(Imagine parts of feature "B" are already staged, now you realize there is feature "A")
cp .git/index .git/index_bak #Save partly staged feature B
git reset #Start again
git add -p #Stage only A
git commit #Commit only A
mv .git/index_bak .git/index #Restore stage. This is now a bit strange
#as it seems to remove feature A. Therefore
#reapply feature A (which is still in the
#working directory) again - only to the stage
git diff -U0 HEAD~1.. | git apply --cached --unidiff-zero
git add -p #Continue stageing B
Upvotes: 2
Views: 242
Reputation: 489113
Besides the answers from poke and VonC, if your Git is at least 2.5, consider using git worktree add
to create a new independent branch, where you can do completely independent work. Note that none of the uncommitted changes (in index and/or work-tree) will be copied to the newly added work-tree, though.
Each work-tree has its own private HEAD
and index (and of course is its own separate work-tree). Git makes a fairly strong constraint: each added work-tree must be on a different branch from every other work-tree (including the main work-tree). However, you can create a new branch during the creation of the new work-tree, which makes this constraint easy to cope with.
Upvotes: 0
Reputation: 388023
As you have noticed, manually messing with the index is kind of difficult. So I would suggest you to get used to a workflow that does not involve working with it.
There are probably a few options you have here that will allow you to split up your work into multiple commits:
The easiest solution would probably to take a look at your changes first, before starting to select the changes you want to commit. That way, you will have to think about what you are going to stage first. So when you have changes for multiple commits in there, you can make that plan first and then just stage those changes that you want to stage for your first commit.
If you have already started staging for a commit and then want to make a different commit instead, you could also reset your index first. Of course, this will throw away what you have already staged, so you have to redo it afterwards, but now you possibly know what you need to stage then, so it could be faster.
One way to make that a bit less problematic would be also to actually undo those changes that you don’t want to include in any commit. So if you are ready to commit but still have debugging code in there which you want to get rid of anyway, you could undo those changes first before resetting your index. So when you then made that other commit, you could possibly just add all changes at once without having to go through everything with git add -p
.
Another way, which is what I do very regularly, is to just commit parts and then rebase those interactively later on. So when you start to stage for commit A, and then encounter stuff for commit B, just commit whatever you have already staged for A. Then do the stuff for commit B and afterwards continue with A again. When you are done with everything, then use interactive rebasing to reorder and merge the commits in the way you want your history to actually look like.
While this is the most complicated way, involving interactive rebasing which is probably a bit more advanced, it also gives you a lot more control over everything and you won’t need to throw away (staging) work, you have already done.
Upvotes: 2
Reputation: 1326994
Don't disrupt the flow of your staging.
Complete your initial commit, then proceed with the one with the feature you notice.
Once you have completed all the staging and made all the commits (locally), you can still do an interactive rebase and reorder those commits.
Upvotes: 3