10 ms·
GitHub's Missing Merge Option
- epage 4y agoWhat I wish github supported was "git rebase && git merge --no-ff", or as Azure DevOps calls it "semi-linear merge". A fairly linear history is a lot easier to read but it is nice to preserve the branch by having a merge-commit.
- saghm 4y agoThat's what I prefer to use when merging locally (often from a cleaned up version of my feature branch). I'd for for it to be added, but at this point I honestly just wish there were a way for me to manually push and then have it be tied to the PR in some way that shows it as "merged" rather than "closed", since that would essentially handle not only my preference but any possible one someone could have in the future. It would be cool if there were some flag I could specify with a PR id or something when pushing, but I'm not really sure that's feasible without some sort of standard protocol, since I don't expect (and wouldn't want!) git to put in Github-specific functionality. I'd certainly settle for some menu item in Github's PR view for a maintainer to be able to do something like select a recent push from a menu to then be attached to the PR's metadata for future viewers, but at this point I doubt it will ever be added.
- q7xvh97o2pDhNrh 4y agoGenuinely asking: What's the value prop of having the merge-commit in the history for you? Have you ever capitalized on it? And if so, could you share the command-line-fu that's helped you take advantage of having such a commit in your repo history? I'm asking because I used to do exactly this and feel much the same way as you — I felt it was nice to preserve the historical context. At some point, it dawned on me that, amidst all the anecdata I'd acquired, I'd never once benefited from having those commits cluttering up the history. These days, I usually advocate "squash & merge" for the 80%+ of teams that lack the discipline to write good commit messages for every one of their branch commits. And, for those rare teams where every engineer writes thoughtful commit messages on their branches (a true delight!), I savor being able to do "git rebase && git merge --ff". Either way, we end up with a lovely linear history of (hopefully) atomic commits.
- seba_dos1 4y agogit log --first-parent git log --graph --oneline As long as we're not talking about single commit merges, these merge commits don't clutter the history; they enrich it.
- chrsig 4y agoit's way easier to revert the merge commit than potentially every commit that was included in it. having everything squashed into one commit can be annoying if the commit is too large, because it can be hard to identify why a specific change was made via git blame. With a merge commit, I can make individual commits for logical changes, potentially rebasing, or squashing commits together. that also gives an opportunity to write more intentional and informative commit messages. once i have a good changeset, I can publish a single PR for review. I've only really taken to this approach lately, for a long time I just didn't care. As the years go by, I care more and more about what git blame can tell me. I've been maintaining some projects for a long time, and I've had to pick up many projects that don't have their original authors available for consultation. In both cases, having a quality git commit log is just a time saver. I don't care about preserving the history from when the code was initially typed, I care about the context the log can provide me about the change sets that have been applied. I've been debating starting to include it in my code reviews: "this commit log needs more details: can you edit the commit message and do a git push --force?" If you're dealing with a more junior team, or people that don't care about the log, it's really a toss up for me. Roll your dice on maybe an informative message helping you, or sift through 15 commits saying "poke", or squash an enormous commit and get a single sentence about it.
- q7xvh97o2pDhNrh 4y ago> I've been debating starting to include it in my code reviews: "this commit log needs more details: can you edit the commit message and do a git push --force?" Strongly agree with this. I hold the line on this for every team I lead (which, sadly, is not every team I consult for, so sometimes I have to keep my mouth shut and spend my political capital elsewhere). Many junior/mid-level engineers have simply never seen commit messages and source control done well. Additionally, because many folks starting out in the field don't know how to truly use git beyond memorizing a few basic commands [1], they also never harvest any of the benefits of writing great commit messages. I've got a stash of links that I find myself often sending to engineers who are on the way up, and the tpope article on git commit messages [2] is one I find myself sharing around constantly. [1]: https://xkcd.com/1597/ https://xkcd.com/1597/ [2]: https://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html https://tbaggery.com/2008/04/19/a-note-about-git-commit-mess...
- sudo_chmod777 4y agoVote here: https://github.com/community/community/discussions/8940 https://github.com/community/community/discussions/8940
- drewcoo 4y agoWell if we're going to start adding wish list items . . . I would like decent distributed bug tracking such that I could follow a bug from first detection through branching and merging and forking until fix and then follow the absence of bug through branching and merging and forking. No more centralized bug trackers. Death to Jira!
- mwint 4y agoIn a perfect TDD world, you could write a test for the bug and let bisect figure out where the bug first appeared and when it was fixed. Hard to do, but when I was at a big company they had something similar.
- masklinn 4y agoGood luck with that. The idea of a distributed bug tracker was in vogue in the first years of the DVCS rise. The problem is that it doesn’t really make any sense, or at least nobody managed to make it make sense: a bug tracker is a synchronisation point, and a bug is a cross-cutting concern, and one which outlives it’s fix.
- kayson 4y agoI'm not sure I'd call Rebase & Merge clean... If you do it you get duplicate commits (the hash is different but the content is the same). It appears clean if you look at the commit history for a given branch on Github, but it's not all that clean in git itself. I work on smaller scale projects and set up a work flow where development is done in a develop branch, and main is locked behind PRs so everything gets CI'd and reviewed before its CD'd. I'm definitely on "Team Clean", because I think it works better for projects of our size, but the only way to get a rebase and ff merge is to do it locally and push to main, which I've blocked for safety. Maybe there's a solution but I couldn't figure one out.
- masklinn 4y ago> I'm not sure I'd call Rebase & Merge clean... If you do it you get duplicate commits Which matters… how? The duplication will disappear when you nuke the development branch.
- MathiasPius 4y agoOne way in which it is useful, is that you can tag your build artifacts (like docker images) with the commit id in the development branch, and just re-tag them when you want to promote the artifact to main or production, or whatever. Without this option, you have to either rely on branch names when promoting, which means you can't tie your build to a specific commit in your main branch anymore[1], or you can rebuild your image from the new commit, potentially producing an entirely different artifact which might differ from the one you just tested and validated on your development branch. [1] Unless you back-fill that information after merge, but the workflow is getting really convoluted at this point.
- seba_dos1 4y agoIf your branch is not fast-forwardable and has to be rebased before merging, then you wouldn't be able to reuse the artifact from development branch anyway as your production branch is already somewhere else than your development branch was. If it is fast-forwardable, then individual commit IDs don't change at all and you only get a single, effectively empty, merge commit on top of them, so you actually can reuse the artifact just fine.
- Ferret7446 4y agoWhy do people think that having branches in their history is "unclean"? I'm struggling to understand what is the issue here.
- yakkityyak 4y agoI'm betting that a perfectly linear git history is probably easier/nicer to have for people who think of git as a sequence of deltas. That is not how git works, but I can understand the appeal. For all my personal projects I squash and merge everything.
- teraflop 4y agoIf you have a Git repository with merge commits that merge changes back into your main branch, all you have to do is "git log --first-parent -m" to get a log that looks exactly as if you had squashed and rebased every change. I'm surprised I don't see more people talking about this option. Sure, the syntax is inelegant, but it seems like it gives you the best of both worlds: you can browse your history as if it was linear, and drill down to the individual commits in a branch only when necessary.
- tsimionescu 4y agoDo Github, GitLab, BitBucket, or any other Git UIs support this option? Relatively few people use the command line for inspecting Git history. Not even sure Magit exposes this option directly in most places where it shows history, I believe.
- zdw 4y agoGerrit has a way to look at all patches uploaded, but only take the last one which should be squashed/rebased, if it's configured that way (The "Fast forward only" option). It results in very clean history, and unmodified commit hashes from a developer's commit, whereas Github's Squash and Merge will mangle the commit message by adding a PR # to it, as well as other comments, which changes the hash. PR #'s are not as good as clean hashes, IMO. As someone who went from an org that was using Gerrit to mandatory Github usage, the latter is definitely a step backwards in code review. That said Github does have a better browsing interface than gitiles.
- u801e 4y ago>> An eternal war rages between team “git log should be clean” vs. team “git log should have an accurate history.” Having a clean commit history makes it easier to utilize commands like git blame and git bisect. I'm not convinced those who want to have an accurate history really understand what they want. For example, if after every single keystroke, I saved the file, added it to the index and ran git commit -F - <(date), then I certainly could have a comprehensive history detailing every single keystroke I made as I edited the code, but the history would not be very useful when looking back on it. >> Team Clean >> Methods: git merge --ff-only or git rebase && git merge (extreme clean freaks add the --squash option) >> Pros: Linear history, git log is easy to read, git revert requires no thought. >> Cons: You’re erasing history—you can no longer tell if two commits were written together on a single feature branch. Could the con not be addressed by using the --no-ff even if it's a fast-foward merge? A merge commit in that situation points to the same tree as the HEAD commit of the branch that was merged, but the merge commit also has the information about the base commit and the head commit of the branch, so you know what commits were in the branch even after it's merged.
- Shorel 4y agoI agree with you in the most general sense. Someone's "accurate history" is just noise to everyone else. Squash and cherry-pick your commits to a public repository, people. Now, multiple people working in parallel is something else, but many times a long set of code experiments is not valuable history.
- eurasiantiger 4y agoIt is valuable history: it is archaeological evidence of what has been attempted before.
- seba_dos1 4y agoIt sure is valuable, which is why it's retained in your reflog. You don't have to push it out anywhere though (or at least not somewhere where it pretends to be part of the project).
- gorgoiler 4y agoThere are two kinds of history: private and public. When you are writing your book, your drafts might be versioned and you might want to revert a chapter or section if it turns out to be of no value. Later on you might want to cherry pick that chapter out of the bin*. That’s all part of the writing process. When your work is complete you have your editor give you feedback on which also use a revision control system. This isn’t quite public but it’s different to the private process in that the changes have semantics related to the decisions making you and your editor take part in. Those decisions need to be recorded in the history of the project. You eventually publish the first edition. Longer periods of time see revisions to the first edition. A friend of mine just finished his third edition ten years after the previous one. These big changes will be made up of many small changes you do want to know about (decisions you and your editor came to) and many you don’t (“wip reverting section 43 / 45 ordering”.) Software is the same. Some people want to publish their entire decision making process. This is a mistake — no one finds value in it, so it should be kept private. Most people are happy for the decision making process to be public (pull request arguments) or at least their outcomes to be visible (ff commits of approved PRs.) Editions of the work (tags and/or release branches) shoul have a git log at the granularity of ideas that were agreed upon and made public as opposed to every single idea we ever had. *Is a writer’s reflog their wastepaper basket or their brain?
- madmax108 4y ago> This is a mistake — no one finds value in it, so it should be kept private. Just anecdotal, but I disagree vehemently. In my experience, an easy way to follow Chesterton's fence ( to figure out why a piece of code is the way it is before modifying it's behaviour), is to understand the decision making process that was being followed and not just the blob of code that added it (Even more so on older repos where the original author may not be around). Many a times, it becomes obvious that the code was written under a very different understanding of the what the system evolved to be, and as such can be changed accordingly, and inversely that the code makes certain strong assumptions when written which hold true even today. This is why as a thumb rule, especially for junior developers just getting started with git, I spend time on getting them to understand good git commit messages instead of 'git add . ; git commit -m "some code"' because I've seen a tonne of value retrospectively in this.
- codeapprove 4y agoAs someone who is a big proponent of "squash and merge" I am susprised to see myself labeled an extreme clean freak! I don't have very extreme git uses or opinions. I want a few things in my team's workflow: * A commit history that a human can mostly understand * Effective code reviews where I can easily see what changed between rounds * The ability to revert a whole Pull Request easily and cleanly * A local workflow that does not get in my way and allows me to be messy when I need to be For our team that means we commit whatever we want to our local branch and then squash and merge the whole thing at the end. The result is a single commit saying "Adds feature foo". I don't feel like I lost anything in the squash ... am I missing something? I really don't want to have "fix lint, address review comments" in the shared commit history.
- jlokier 4y ago> The result is a single commit saying "Adds feature foo". I don't feel like I lost anything in the squash ... am I missing something? I really don't want to have "fix lint, address review comments" in the shared commit history. Neither. If you're doing it then way it's done in Linux, you will end up with neither of those. Instead you will have: "Add a new geometric engine with tests", "Add the geometric engine to view API keeping backward compat", "Use the new view API extensions in the main window renderer", "Implement behaviours for feature foo in the renderer", "Hook up scripting extensions, keys and menu options to make feature foo user-accessible", "Add basic documentation for feature foo". No "lint", "reviewer feedback", "fix typos" or "I changed my mind and reverted the last revert" trivia goes in the history. You should not in general submit your minute by minute trivial actions, indeed the commits submitted are usually not even in the same order as they were written and refined Nor are the above individually complex, logical, meaningfully revertable and bisectable changes squashed down to an unhelpfully crude one-liner "Add feature foo" with a 5,000 line diff that touches most files in the project. Some would say the logical changes should be separate PRs. To some extent, but it depends how fast you wrote the feature, whether the round trips make sense, and how involved in the nitty gritty you want the feedback to be. The ideal unit of review or feedback, ie PR size, is often larger than the unit of a logical change. That's because the "future why" is not so apparent with individual changes, so people tend to zoom into the weeds instead of using appropriate context. In so doing they also tend to use up their reviewer attention budget so the other changes don't get the same scrutiny. Think about the feedback to the first big logical change "Add a new geometric engine with tests": "Why are you adding this? What is the motivation?", or "This works but the API has these unnecessary warts" (warts you have to explain will be necessary in 3 PRs time). You can either have a chat in the PR feedback where you have to persuade someone that the rest of your plan makes sense, not easy if they can't see how it does. Or you can present the later changes all together as a group and then the code speaks for itself, much more convincingly.
- melonrusk 4y agoI have no idea what this article is talking about, but if there are two plausible representations for the whatever-it-is, why not allow it to be represented both ways ?