Hacker News new | ask | show | jobs
by smithzvk 5011 days ago
Okay, that is basically keeping with my current understanding (though I'm not sure how much I live up to the "only have working history in the public repo" rule).

There is the other issue I raised, however: is there a good way to group a series of commits that happen to be towards a single distinct goal. Using branches is a clear step in that direction, but it seems like a nightmare to perform a rebase like you described if the commits are mixed and I would like the end result to involve grouping via branches. That is confusing, hopefully this will clear it up:

1. Bugfix in function1. 2. Bugfix in function2. 3. New feature in function2. 4. Bugfix in function1. 5. Bugfix in function2

...and we want in the end:

      /-- 1 ---- 4 ---\
  ---<                 >--HEAD
      \- 2 -- 3 -- 5 -/
Can rebase do this easily? Is this a good idea (it seems like it is to me)? The programmer would have to confirm that the code works at every state.
2 comments

So I'm not sure if I understand correctly, but let me put it this way: with a little more git craziness, you can crack apart a commit and separate it into two. This is good if you did two unrelated changes to a file, committed that, and realized you wanted two separate commits later.

The basic process is:

1. git rebase -i, and change a commit to 'edit' 2. git reset HEAD^, this 'undoes' the commit and leaves the changes in your directory as if you had written the code but hadn't committed it yet 3. git status 4. git add <filename> -p, this lets you add commits to your file a chunk at a time. first, add all the commits as a part of commit one. skip the parts you want for commit two. 5. git commit (do not do git commit -a here) and write the message for your first commit 6. now your working directory will be all the changes for commit two. git commit -a if you want all of them 7. git rebase --continue

This page[1] has a more concise answer, but leaves out the git commit -p part.

Note that if you mess up in rebase-land, you can always git rebase --abort. If you come out of the rebase and everything looks lost ('oh god I lost my data!'), use git reflog and pull up the hash of where you were before. Your data is still there.

Another note: if your commits are already separate, you can use rebase to selectively squash and reorder them. Read the manual on git rebase -i, if you rearrange commits and only squash some I think you'll get what I'm talking about.

[1] http://stackoverflow.com/questions/6217156/how-to-break-a-pr...

Switching branches is cheap, I'd say the "right" way to get a tree like you want is to have two or even five branches all the time you're working. But I suspect you could make two branches and cherry-pick different sets of commits onto them to get the result you're after. To my mind it wouldn't be worth the effort though; how often do you really care whether the code worked with only 1 and 4 applied?
Right, I would say that it isn't worth the effort. Also, I probably never care about the code with only 1 and 4 applied. So perhaps branches aren't the right way to do what I am describing.

I always saw VC as a systematic way to keep a log of my development so that I could figure out where I may have broken my code. For this purpose, having some sort of meta-data where commits can be grouped would be nice. It would also work to do something like always end my commit messages with some kind of meta-data tag that I could grep the log for. I was just wondering if there was a prescribed/built-in way for Git to handle this.

git-bisect is the standard tool for figuring out where you broke something. I don't know what it does with branching histories though, I tend to effectively linearise my history by rebasing each branch on the trunk head before merging it.