I'd suggest adding hunks instead of committing them so you can review your staging area at the end. It's the same flag; just use 'git add -p' instead of 'git commit -p'.
FYI, in case you added reaaally a lot of stuff, and want to split it into smaller commits, it might be much more handy to do partial commits using Git GUI (select lines in the file & right click to have a popup menu with appropriate option). Also, don't do it the next time.
Side hint: for things like fixing typos, I found that creating a new branch, say 'typos', is quite handy solution to not do these kind of things in the commits that are meant to add new things / fix bugs. Just checkout typos, fix, commit, checkout master / feature branch.
> Side hint: for things like fixing typos, I found that creating a new branch, say 'typos', is quite handy solution to not do these kind of things in the commits that are meant to add new things / fix bugs. Just checkout typos, fix, commit, checkout master / feature branch.
Could you maybe elaborate on this a little bit more? I don't think I quite understand this.
My understanding is that you'd have to do a 'git merge master' after you checkout 'typos', make the fix, commit, and then a 'git merge typos' after you checkout 'master'. Then wouldn't this add all of the typos commits into the master branch anyway?
I'm very likely missing something fundamental. (Perhaps my source control habits aren't up to snuff.)
Yep I wrote this with too much shortcuts. What I do is: git checkout typos, git rebase master, [fix typo & commit], git checkout master. This way I accumulate typo fixes in a separate branch, and merge a couple of them at once to master when I see fit (perhaps squashing the typo commits into one beforehand).
For typos, `commit --fixup` is an invaluable tool.
It creates commits with a special name that will be recognized `git rebase -i --autosquash`. It will merge commits with their fixups (+ whatever you want to do with `rebase -i`).
I was originally referring to fixing old typos (like spelling in documentation) that were in the repo forever.
This, from what I understand this will take effect only if you introduced a typo recently and then you rebase so that the typo-containing commit is included in the rebase. Nevertheless, it sounds interesting.
Still unsolved: ensure your commits are not broken (aka pass all tests) without stashing everything else (in which case you could just as well stash the stuff you don't want in patch mode using `git stash -p`).
(even if they are in a feature branch, broken commits will break `git bisect` unless the branch is folded when merged)
Not necessarily. Use patch mode (or a tool like GitX that does the same job), commit, then stash and run your tests. If it's broken, amend your commit, rinse and repeat. Then push your changes or pop the stash and continue development.
I am not sure why you insist on not stashing the rest of your working directory ? This is a nice and non-permanent solution.
There's a difference between `stash -p` and `add -p + stash`, though. If you want to split your changes into more than two commits, you have to use add/commit/add/commit because stash will just make a commit with "what's left" (it's subtractive operation).
Skip means you can't run scripted bisects (such as `bisect run make test` or however that's spelled using your test runner) and either way when you reach a broken commit you have to determine whether it's broken due to what you're looking for or for some other reason, which means time wasted.
skip is necessary when your history is broken and fucked, but I'd just as well not have a broken and fucked history in the first place.
No, if your script exits with exit code 125, then that means "skip". You just need to write a wrapper script that'll handle that, so "make || exit 125 ; ./test-if-commit-is-good.sh" can do it.
IIRC, you can clone the repo (leaving behind uncommitted changes) and run tests from that folder. Which also lets you run multiple tests in parallel if they're long, and continue to develop on your other branch, and ensures you have no absolute paths :) Cloning only takes a few seconds for even pretty large repos since it hardlinks everything.
Create commits using `add -p` up to the point that the current state of the work tree is fully committed. (You can `reset HEAD^` if you need to add some stuff that you do not want to become part of your branch's history, at least not in its current form.) Then test using run-command-on-git-revisions[1] on the new commits.
This lets you create multiple commits at the same time and run tests on all of them. You could argue that committing and resetting is effectively the same thing as stashing and popping, but I think the benefits of being able to iterate over a list of commits and test each one is worth creating additional commits that you will probably reset shortly after testing.
This is also what you should do after a rebase to test all affected commits as they have not neccesarily existed in a testable state in the work tree.
Ah, another "git -p" article. Funny thing is, I didn't even know about the "-p" option until I looked it up, even though I was using it all the time indirectly through Egg (Emacs Got Git). The sad part is, though, separating changes doesn't completely solve the problem (I often get lines overlapping between bug fixes, cleanups and new features). More than anything, discipline comes into it, but at least git makes it easier (especially with the fast branching). Another interesting take on Git's patch mode: http://tomayko.com/writings/the-thing-about-git
25 comments
[ 2.6 ms ] story [ 66.3 ms ] threadSide hint: for things like fixing typos, I found that creating a new branch, say 'typos', is quite handy solution to not do these kind of things in the commits that are meant to add new things / fix bugs. Just checkout typos, fix, commit, checkout master / feature branch.
Could you maybe elaborate on this a little bit more? I don't think I quite understand this.
My understanding is that you'd have to do a 'git merge master' after you checkout 'typos', make the fix, commit, and then a 'git merge typos' after you checkout 'master'. Then wouldn't this add all of the typos commits into the master branch anyway?
I'm very likely missing something fundamental. (Perhaps my source control habits aren't up to snuff.)
It creates commits with a special name that will be recognized `git rebase -i --autosquash`. It will merge commits with their fixups (+ whatever you want to do with `rebase -i`).
This, from what I understand this will take effect only if you introduced a typo recently and then you rebase so that the typo-containing commit is included in the rebase. Nevertheless, it sounds interesting.
(even if they are in a feature branch, broken commits will break `git bisect` unless the branch is folded when merged)
> without stashing everything else
and noted that if you're going to stash the rest either way you could just as well use `stash -p` in the first place.
There's a difference between `stash -p` and `add -p + stash`, though. If you want to split your changes into more than two commits, you have to use add/commit/add/commit because stash will just make a commit with "what's left" (it's subtractive operation).
skip is necessary when your history is broken and fucked, but I'd just as well not have a broken and fucked history in the first place.
No, if your script exits with exit code 125, then that means "skip". You just need to write a wrapper script that'll handle that, so "make || exit 125 ; ./test-if-commit-is-good.sh" can do it.
This lets you create multiple commits at the same time and run tests on all of them. You could argue that committing and resetting is effectively the same thing as stashing and popping, but I think the benefits of being able to iterate over a list of commits and test each one is worth creating additional commits that you will probably reset shortly after testing.
This is also what you should do after a rebase to test all affected commits as they have not neccesarily existed in a testable state in the work tree.
[1] https://github.com/garybernhardt/dotfiles/blob/master/bin/ru...