Live data from Hacker News

Understanding the Git Workflow

sandofsky.com

21–30 of 78 posts

Re: Understanding the Git Workflow

#21
post #12
post #8

Earlier quoted context omitted.

I would never ever rewrite the public history. The public history is what ends up on the repository from where we deploy from. Whenever a commit is pushed there, it stays there. There will never be any rebasing (minus emergencies like removing accidentally committed files for which we don't own a license for - didn't happen so far though). "rebase -i" is a tool for personal development use. It's not a tool to use on…

IMO, that's really the wrong way to go, and it's one of the big reasons I absolutely loathe git. I want any changes that are in my tree, ever, to be in the order and position in which they happened. If somebody screwed up and forgot to add a file, fine--add it in another commit. It's not like commits cost money. As far as rolling back later--meh? I've never had a trouble in 300Krev heavily branched SVN barf, I strong…

Why, then, not commit every keystroke? After all, you're losing history every time someone types backspace.

I imagine the reason that seems absurd is that you don't consider all the false steps and reworking that go on while a commit is crafted to be part of its official meaning. The working set is malleable until it's ready, and then you commit it. Well, private branches as pilif describes them are malleable in just this way. In both cases, you work your code like clay until it's ready to be presented and then bake it in to the public history.

Re: Understanding the Git Workflow

#22
post #17

I work this way and agree about the value of a clean, linear history. It makes working with past versions of your code a breeze. There's one thing the OP doesn't mention that I've found important. Say you're working on a major design change in a private branch and it has 100 commits. When it's ready to be put on top of master, you'd really like not to squash all 100 commits. Unfortunately, if there are conflicts, the…

Here's a trick for you: make sure you have rerere enabled. Merge the end commit, resolve all the conflicts and commit the merge (or just run rerere to record the conflict resolution). Then abort the merge or reset back to undo it. Now do the rebase, which will re-use the resolutions for any identical conflicts. You still have to deal with conflicts unique to the intermediate state, but in my experience rerere helps a lot.

Re: Understanding the Git Workflow

#23
post #20
post #14

Earlier quoted context omitted.

It wouldn't mine, if I used git (I avoid git specifically for this reason, actually, and use Mercurial). If you're actually looking at your commit logs, I find that rolling back is trivial; I can't remember the last time I accidentally rolled back into an incremental commit. Personally it feels more like an apology for git's bad behavior than a good method of development.

What exactly does Mercurial do differently that is better?

Short of explicitly installing a rebase extension, it simply does not allow you to do this sort of mucking about with the commit history. For "oops, typo" commits, you can very quickly (and I mean, "it's a button in Tortoise" quickly) roll back your change and keep it in abeyance until you've fixed the typo.

Re: Understanding the Git Workflow

#24
post #22
post #17

I work this way and agree about the value of a clean, linear history. It makes working with past versions of your code a breeze. There's one thing the OP doesn't mention that I've found important. Say you're working on a major design change in a private branch and it has 100 commits. When it's ready to be put on top of master, you'd really like not to squash all 100 commits. Unfortunately, if there are conflicts, the…

Here's a trick for you: make sure you have rerere enabled. Merge the end commit, resolve all the conflicts and commit the merge (or just run rerere to record the conflict resolution). Then abort the merge or reset back to undo it. Now do the rebase, which will re-use the resolutions for any identical conflicts. You still have to deal with conflicts unique to the intermediate state, but in my experience rerere helps a…

I tried rerere once and it felt too much like magic to me, i.e. too complicated in a way that I didn't trust. Experience with conflicts has led me to eschew magic merge tools and rely on the simplest strategies: 1. minimize conflicts; 2. bite the bullet and deal with them manually. (Edit: my question about rerere is: how identical is "identical"? How can I be sure that it will redo what I did before in exactly the way I would do it now? Doesn't it have to understand my intent to achieve that?)

The diligent-rebasing-along-the-way workflow I proposed is all about #1. You still have to deal with intermediate conflicts this way too, but at least they're minimized. If something you commit to master conflicts with my B49, I have to fix B1..B49 but at least I can write B50..B100 in a way that takes your work into account.

Re: Understanding the Git Workflow

#25
post #18
post #12

Earlier quoted context omitted.

IMO, that's really the wrong way to go, and it's one of the big reasons I absolutely loathe git. I want any changes that are in my tree, ever, to be in the order and position in which they happened. If somebody screwed up and forgot to add a file, fine--add it in another commit. It's not like commits cost money. As far as rolling back later--meh? I've never had a trouble in 300Krev heavily branched SVN barf, I strong…

Commits don't cost money, but time wasted on "added forgotten files"-commits while parsing the history to trace a bug does cost money, so I'd rather not have the commits. Additionally, it's impossible for you or anybody else to find out whether I have rebased my personal history before pushing. As such, it's totally inconsequential for the main repository whether I rebased or not. As I said: I think rebase is a perso…

I dunno, I think the claim that those commits "waste time" (in the sense of any meaningful amount of time, even cumulatively) is a little hyperbolic.

I guess you view history differently than I do: I consider all development history to be "public history" regardless of whether it was pulled in from a clone or not. If you commit it to a repository I am going to be fulfilling a pull request from, I want the history there.

Re: Understanding the Git Workflow

#26
post #21
post #12

Earlier quoted context omitted.

IMO, that's really the wrong way to go, and it's one of the big reasons I absolutely loathe git. I want any changes that are in my tree, ever, to be in the order and position in which they happened. If somebody screwed up and forgot to add a file, fine--add it in another commit. It's not like commits cost money. As far as rolling back later--meh? I've never had a trouble in 300Krev heavily branched SVN barf, I strong…

Why, then, not commit every keystroke? After all, you're losing history every time someone types backspace. I imagine the reason that seems absurd is that you don't consider all the false steps and reworking that go on while a commit is crafted to be part of its official meaning. The working set is malleable until it's ready, and then you commit it. Well, private branches as pilif describes them are malleable in just…

I strongly dispute the assertion that a private clone is malleable in the way you're describing. I consider all history important enough to be committed to be "public" history. But (apparently unlike folks who are fast with their downvote buttons) I certainly acknowledge that it is a matter of taste.

Re: Understanding the Git Workflow

#27
post #26
post #21

Earlier quoted context omitted.

Why, then, not commit every keystroke? After all, you're losing history every time someone types backspace. I imagine the reason that seems absurd is that you don't consider all the false steps and reworking that go on while a commit is crafted to be part of its official meaning. The working set is malleable until it's ready, and then you commit it. Well, private branches as pilif describes them are malleable in just…

I strongly dispute the assertion that a private clone is malleable in the way you're describing. I consider all history important enough to be committed to be "public" history. But (apparently unlike folks who are fast with their downvote buttons) I certainly acknowledge that it is a matter of taste.

I consider all history important enough to be committed to be "public" history

This argument seems to me to boil down to an attachment to a single meaning (the traditional one) of the word "commit".

p.s. Instead of complaining about being downvoted, it would be better to make your tone less aggressive in the first place. None of your other comments made it clear that you regard this as taste; actually quite the opposite.

Re: Understanding the Git Workflow

#28
The idea that fast-forward merges are easier to follow is subjective. I find my --no-ff history easier to read. This author doesn't.

What always using fast-forward merges really means is that you rebase each branch onto master once it's ready to be public. Therefore, instead of resolving conflicts when the branch is merged, the commits are rewritten to avoid introducing the conflict in the first place.

Sometimes, this is really simple -- I added a line in one spot, you added another line in the same spot, you merged first, so I rewrite my commit to add my line next to yours instead of merging and resolving the conflict. Sometimes, it's not -- maybe there's not even any text-level conflict, but your feature and my feature interact in subtle and unanticipated ways and something breaks. Now, there's no "good" point in my branch to refer to, because I rewrote it on top of something where (I didn't realize) it was never really going to work. The unit test I now need couldn't have existed because it involves things that, when I was developing the branch, didn't exist.

Rebasing first is trading off when you do that work. There's more to review when the branch is ready, and there's a stronger incentive to get it right the first time. I think this may work better for the "two founders deploying from master when they feel like it" scenario -- you pay for manageability with context switches. If you have a formal QA process, I think being able to distinguish between "this branch failed QA" and "the combination of these branches failed" may be more helpful -- you can parallelize work and hack on a different private branch.

Git, thankfully, does not force us to choose one model or the other :-)

Re: Understanding the Git Workflow

#29
post #25
post #18

Earlier quoted context omitted.

Commits don't cost money, but time wasted on "added forgotten files"-commits while parsing the history to trace a bug does cost money, so I'd rather not have the commits. Additionally, it's impossible for you or anybody else to find out whether I have rebased my personal history before pushing. As such, it's totally inconsequential for the main repository whether I rebased or not. As I said: I think rebase is a perso…

I dunno, I think the claim that those commits "waste time" (in the sense of any meaningful amount of time, even cumulatively) is a little hyperbolic. I guess you view history differently than I do: I consider all development history to be "public history" regardless of whether it was pulled in from a clone or not. If you commit it to a repository I am going to be fulfilling a pull request from, I want the history the…

and you will get that history.

But you will get it in the form that I would like you to have it, not as it happened.

But there is no way for you to know besides the fact that all commits you are going to pull are self-contained and none of them breaks the build.

Would you reject perfect looking commits, self-contained, perfectly documented and forming a perfect temporal history based on the fact that they are too perfect not to have been created using rebase? Because that's the only indication you have that rebase was used.

Re: Understanding the Git Workflow

#30
post #25
post #18

Earlier quoted context omitted.

Commits don't cost money, but time wasted on "added forgotten files"-commits while parsing the history to trace a bug does cost money, so I'd rather not have the commits. Additionally, it's impossible for you or anybody else to find out whether I have rebased my personal history before pushing. As such, it's totally inconsequential for the main repository whether I rebased or not. As I said: I think rebase is a perso…

I dunno, I think the claim that those commits "waste time" (in the sense of any meaningful amount of time, even cumulatively) is a little hyperbolic. I guess you view history differently than I do: I consider all development history to be "public history" regardless of whether it was pulled in from a clone or not. If you commit it to a repository I am going to be fulfilling a pull request from, I want the history the…

I completely agree with this.

If a change was worth committing then it is worth sharing that commit with everyone. Otherwise you run the very real risk of loosing important information about the design of a feature the bugs that were found and addressed during development.

Every change should been accompanied by a well described commit message and big changes are much harder to review.

I can see a very small positive in "hiding" the commits which resolve process issues like forgetting to add a file but in the long run you shouldn't have very many of these anyway so you should worry about them.

Post reply on HN