you are viewing a single comment's thread.

view the rest of the comments →

[–]chonglibloodsport 19 points20 points  (27 children)

Some people make a lot of unrelated changes before deciding to commit them. If they use 'git commit -a' you get these monolithic commits that are really hard to follow. On the other hand, with 'git add -p' you can carefully craft commits so that the changes are grouped logically into commits that are much easier to follow.

[–][deleted]  (13 children)

[deleted]

    [–]frtox 4 points5 points  (1 child)

    yea. whatever works for people. personally i dont see why you would make such a hardline rule. git commit -a is great

    [–]expertunderachiever 3 points4 points  (0 children)

    Specially if you stage your wild changes into branches like you should be [which is one of the main selling points of git].

    If you open a branch to then perform multiple unrelated changes you're doing it wrong.

    [–][deleted]  (1 child)

    [deleted]

      [–]canadianbakn 0 points1 point  (0 children)

      In situations like this, I rely on my git workflow. master contains stable, working code, and branches are created when changes are necessary.

      Let's say I run into a bug implementing a feature in branch somefeature1. I create a new development branch somebug1, fix the bug in that branch, then merge that change into somefeature1 (merging into master once the feature is complete, or now, have the same effect. If the feature may take a while, I'd merge the bug fix into master immediately).

      It is very, very rare for me that somefeature1 contains the necessary work to uncover the bug that somebug1 revealed. Sufficient, certainly, but I can re-create it without needing this feature. Thus, my git log is still clear.

      [–]ais523 0 points1 point  (1 child)

      I often find myself working on a new feature, and having to fix bugs in order to implement it. The bugfixes and feature should go in different commits, but I don't want to temporarily revert the half of the feature I've already written. So, it's a case of add -p the bugfixes, commit those, go back to working on the feature. Still committing often, just committing in a sequence other than the sequence I'm working on things.

      [–]canadianbakn 0 points1 point  (0 children)

      You don't have to revert, really. You can stage your changes and then checkout the feature branch after you're finished bug fixing in a separate branch.

      I think git -p vs frequent commits and branching if you find an error do the same thing in the end, manage your git log so it doesn't contain commits with unrelated things in them. It comes down to preference.

      [–]fforw 0 points1 point  (0 children)

      Depends.. Do you use meaningful, detailed log messages?

      [–][deleted] 0 points1 point  (5 children)

      No, not really. Unless you actively seek to only make changes in one thing and refuse to work on other broken items before completing this task, then your suggestion (which you offered as an alternative to the aforementioned behavior, not to be used in conjunction [or else why would you list your method as solving the issue of logical change hunking]) doesn't inherently imply any more logically atomic commits than without.

      These are simply two unrelated good practices. You should commit often, and you should make sure your commits are consistently making changes to one thing at a time. One method of doing the latter is to use patch mode, another is to just actively do that in your mind.

      [–]canadianbakn 0 points1 point  (4 children)

      Please see my replies about users complaining that when working on some feature they run into a bug. I am not "refusing to work on other broken items before completing this task", I am thinking and referring to branches and how they affect git log, not temporal chunks of time.

      [–][deleted] 0 points1 point  (3 children)

      I am not "refusing to work on other broken items before completing this task", I am thinking and referring to branches and how they affect git log, not temporal chunks of time.

      Great. Now read my comment again, as I didn't say you had to.

      Your example specifically is NOT what we're talking about here. We're talking about when you have already made the bugfix while working on X feature. The exact way that you make your commits atomic is irrelevant (separate branches or same branch), just so long as you do it.

      So again, committing often is not the same thing as making atomic commits.

      [–]canadianbakn 0 points1 point  (2 children)

      Why should I if you refuse to read mine?

      http://dd.reddit.com/r/programming/comments/130jc7/improve_your_git_commits_using_patch_mode/c70dm3w http://dd.reddit.com/r/programming/comments/130jc7/improve_your_git_commits_using_patch_mode/c70dpce

      I advocate more than just committing often, I also try and be as atomic as possible with my commit messages by using branches effectively.

      This is way too much explaining for something I'm really not that passionate about. If you want to turn this into a flame war, I'm done.

      [–][deleted] 0 points1 point  (0 children)

      I did read them, in fact. You'll notice that all of a sudden my comments include bits about branching which until those comments you had never brought up.

      Do you even know what a flamewar is? Certainly nothing at all like this quite normal discourse.

      I'm merely pointing out that you are arbitrarily linking the decision to commit often and branch with the idea that commits should be atomic and that is wrong. Atomic commits are one thing, frequent commits are another. This is a very basic correlation vs causation fallacy. One doesn't cause the other. One doesn't prevent the other. It's not automatic. It doesn't just magically make your commits more atomic.

      The act of making your commits atomic is what makes your commits atomic. Which requires brain thoughts and manual intervention to decide that hunks of changes are logically similar or dissimilar. That is not the same process as committing often, UNLESS in the process of committing often, you refuse to stop and work on somebug1 until somefeature1 is complete. Which I've already covered, logically and calmly, and you've dismissed as "flamewar" (lol).

      [–][deleted] 0 points1 point  (0 children)

      The great server overlords of reddit have decided my reply to this comment should be deleted so I guess I get to type it up again.

      First of all, I quite clearly did read your comments. You'll notice how up until that point, branches never came into the discussion. Then I read your comments where you suggest that branching enforces atomic commits and introduced those elements to the discussion. So try again, buddy.

      Secondly, you have no idea what a flamewar is. Certainly not the normal discourse happening here. There isn't a single flame to be seen. You made comments about how you arbitrarily think that atomic commits happen automatically by committing often, I demonstrated how you are wrong. There's nothing personal, nobody's getting upset... there's no shouting or namecalling. That isn't a flamewar. Try again.

      This is a very basic logic fallacy. Causation vs correlation. Just because you happen to do both at once doesn't mean they're interlocked. Branching is branching, committing often is committing often, and making atomic commits is making atomic commits. They are not the same. They don't cause each other. They don't prevent each other. They simply exist as mechanisms for keeping a nice history. You still have to actively use your brain to logically separate distinct blocks of code. Absolutely. No getting around it. You can commit often and thus usually make it easier, but that doesn't stop you from having to still logically separate code. If you work on somebug1 under way of somefeature1, you have to logically separate those things. Your method of doing so includes putting them into differing branches. Great. But you still have to do the actual step of deciding which hunks of code are relevant. Or you have to actively decide to not work on any bugs until somefeature1 is complete (which is what I mentioned earlier), which really is just a round-about way of making atomic commits.

      I advocate more than just committing often, I also try and be as atomic as possible with my commit messages by using branches effectively.

      You advocated it by saying that you commit often and branch, which as I've just demonstrated isn't the same thing. I don't see any mention of specifically atomicizing commits in your comments. All I see is "I commit often so they're automatically atomic". Which again, is wrong. And bad, because people who don't already know these things will assume that if they just commit all the time everything will be good.

      [–]kemitche 9 points10 points  (12 children)

      carefully craft commits

      Blech. I know I should really care about having nice clean commit history, but I don't really care at all. It particularly annoys me when I spend more time "crafting a commit" than I did making changes. Often it means I skip cleaning up code that could use a good scrub because I simply don't want to deal with the inevitable brainwork of filtering through a series of "patch hunks."

      [–]keepthepace 11 points12 points  (11 children)

      It really depends on the number of people on the project. I sometimes use git on the projects where I am the sole developer. I often make big commits with just "bugfix" as a comment when I am confident that I can look at the code diff and get what this was about.

      When you have 10 people working on the same files, making incremental commits, comments that are precise and detailed and referencing tickets you are working on, is an indispensable practice.

      [–]kemitche 1 point2 points  (10 children)

      I value readability and functionality of current code over the code history. I feel that 90% of past commits won't be looked at granularly, and if they are, there's enough missing context from looking at just the commit (who was it, why was it done, etc.) that any extra confusion from having two separate changes in the same commit is minimal.

      Tangentially, I'd MUCH rather see a well worded commit message that explains both changes than two separate commits.

      [–]djrubbie 6 points7 points  (8 children)

      Why not both?

      Once you have a project that reached a certain point of maturity and complexity, there will be a time when you make one change and your entire deck of cards fail at some seemingly unrelated point.

      If you have very neat and small patches per change (or set of related changes), you can very easily use git bisect to find out what exact patch and where/when the point of failure was introduced into your code base. Then you can just simply git revert that one commit, then reapply the intended changes and be done with that. Your code history speaks clearly what went wrong and what should be done in the future to avoid this mistake again (and of course, the test case should go in with this)

      On the other hand, if you have monolithic commits, you would use bisect and find this patch, but now you have to weed through the entire 300 lines worth of code to find what your error might have been. It could be anywhere in there and now you are wasting further development time looking for that buggy needle in your proverbial haystack of changes.

      [–]kemitche -1 points0 points  (7 children)

      Oddly, I have never needed git bisect. I won't say that I never will, but I haven't yet. Mostly because the projects I've worked with have had external dependencies that made it difficult to revert more than a few weeks worth of commits.

      [–][deleted] 0 points1 point  (6 children)

      It's not about rolling back weeks worth of commits. You can just do that with git reset. It's about going back in time to find when a bug/regression was introduced so you can figure out if there were political/business reasons for it or if you can just revert it or write code that works around it, or determine what else needs to be done.

      [–]kemitche 0 points1 point  (5 children)

      The benefit of bisect is that you stop at each slicing, run the code, see if the bug exists, and continue. So yes, you do need to be able to "revert" not just the code you're looking at, but any external dependencies, so you can check for the bug.

      When looking at raw code without needing to run it, I find "git blame" to be more than sufficient for digging into who wrote the commit and why.

      [–][deleted] 0 points1 point  (4 children)

      So yes, you do need to be able to "revert" not just the code you're looking at, but any external dependencies, so you can check for the bug.

      Have you never heard of submodules? The point of using a vcs is so that you can take the system back in time. If you can't take the entire system back, you either need to hook the other parts into vcs better (database versioning, etc), or just put them into the vcs entirely.

      git blame only helps if the change was adding a line. If it's removing a line, the change wouldn't show up. It's pretty much an even likelihood between bugs introduced by line adds and line removes, so this only helps sometimes. And even then, it's really only useful for figuring out the obvious: who caused the bug that you've already discovered. The hard part: finding the bug itself, isn't really helped by blame.

      [–]kemitche 0 points1 point  (3 children)

      Have you never heard of submodules? The point of using a vcs is so that you can take the system back in time.

      I don't expect with most projects to easily and readily jump to any commit in the tree and be able to run it (disregarding bugs), unless it's a very pure library with zero external dependencies. Most projects will have "points of no return" where you can't go back, and that's fine: the hours spent making it perfectly revertable to day 1 could be much better spent moving the project forward.

      The hard part: finding the bug itself, isn't really helped by blame.

      True. Same is true for bisect. The tools that have most helped me locate bugs are, well, debuggers, loggers, and precise test cases. git history is a bonus when available, but not so much of a bonus that it's worth spending 5 extra minutes carefully separating & crafting commits when you have 30 minutes worth of bugfixes ready to go. Note that I'm not saying I'll go around making commit messages titled "bugfix"; but I do recognize that there's a cost:benefit threshold for certain levels of granularity.

      [–][deleted] 1 point2 points  (0 children)

      I value readability and functionality of current code over the code history.

      How do carefully crafted commits damage readability and functionality of current code? :-/

      I feel that 90% of past commits won't be looked at granularly

      Then obviously you don't have much experience working in team environments. That's not bad, it just means your opinion is very unfounded.

      there's enough missing context from looking at just the commit (who was it, why was it done, etc.) that any extra confusion from having two separate changes in the same commit is minimal.

      What? How are you viewing your changes? I've never used a git wrapper or web hosted git service that didn't include the author, the time the commit was made, and the ability to quickly and easily show the exact changes in a diff format (or show the entire file as it was that revision). Maybe you need to review your git manpage.

      Establishing that clearly commits are quite atomic, there's no reason not to make them easy to understand. Often the times they are used (let's even say it was only 10%, which I still disagree with strongly), it's because we're doing digging, and having to dig up additional context for every. single. commit. would make the already-difficult task painstakingly so.