18 ms·
Things I wish Git had: Commit groups
- Phlogistique 5y agoThis is possible by doing this: git checkout feature git rebase main git checkout main git merge --no-ff feature
- jlarky2012 5y agoI was going to post exactly the same. Bonus point you can make it work like that in GitLab (but not GitHub)
- svalorzen 5y agoThis is what I also do. I rebase all my branches and merge them with a no-fast-forward commit, which does not introduce any changes itself, but can be used to document the overall changes of a specific feature. The best part about this workflow is that history remains linear; it is very easy to track the history of changes (since there is never a "branch" with changes on both sides) while at the same time you keep the ability to visualize where the start/end points for a given feature were. It also works with nested branches! You simply create a new branch2 from your branch1, and then merge --no-ff branch2 to branch1.
- scooble 5y agoYou also get to write a nice detailed commit message for the merge commit explaining the purpose of the branch being merged, which may not be apparent from the individual commits. Without the merge commit I’m not sure where this would go.
- larusso 5y agoIsn’t that what GitHub does when the rebase strategy. Because when the rebase can’t be made cleanly GitHub still asks for conflict resolution.
- finnthehuman 5y agoI came to the comments to post the same thing. --no-ff is under appreciated. I like that this poster is at least thinking about what he wants the history to look like, but you’ll never get it good with a broad rule. It really takes the exercise of rewriting every change you make from a stream of consciousness set of WIP commits into a logical series of incremental patches with clear commit messages. And doing that every time you want to push anything (especially when it is “just” a WIP or feature branch). After a months practice your sense of taste will kick in and tell you if a --no-ff merge seems appropriate for the current chunk of work.
- ufo 5y agoOn Github the workflow we use for this is rebase in the command line and then press the "Create a merge commit" button in the web UI.
- koo6 5y agoright, and then git log --first-parent
- deleted 5y ago[deleted]
- georgyo 5y agoI too wish for this. Some people are really great at writing commit messages, most are not. But for even for the ones who write the best commit messages, often their is a lot of discussion inside the actual MR which never makes it into git. GitLab and GitHub write a merge commit that can be used to get back to that discussion, but a git blame or bisect doesn't take you to the merge commit, which means you have to spend a fair amount of effort to get to the merge commit. Treating merges as a group would be amazing. Something but addressed in the article is how you deal with groups of groups of groups of merges. IE topic, feature, dev, master branches. It would be somewhat difficult to make the tooling graceful at ungrouping different levels of groups.
- namibj 5y ago--first-parent works for both bisect and blame.
- mitko 5y agoThe author might enjoy `git rebase -i main`, which allows reordering, renaming, combining or pretty much everything in your own branch before you rebase and merge it to the main branch. That way even if a commit message is not clear or you added an improvement to an earlier commit, you can reduce the clutter a lot before sending out for code review, while still having individual commits for different parts of the code change
- martijnvds 5y agoDoing that will kind of work, but you'll lose the context of the group after merging/fast-forwarding onto the main branch.
- frutiger 5y agoIf you always create a merge commit, you can see the group as you traverse the history via the two parent commits. One will walk the group and the other will go directly to the state before the group.
- tolmasky 5y agoI had the similar thought a little while ago (I called them nested commits): https://twitter.com/tolmasky/status/1212452048618131456?s=21 https://twitter.com/tolmasky/status/1212452048618131456?s=21 In my version, the nesting can be infinite of course (I guess the author here would call these "groups of groups" -- but that might be complicated with the flat approach of a group being a range of commits). But basically, I want the UI of an entire "set of commits", but then a disclosure triangle to be able to see the "true history" if it's interesting to me. It is simply the case that sometimes one is more useful than the other, and other times the reverse is true. There simply isn't a one-size-fits-all solution. As far as most people are concerned, you only ever want to, for example, unroll the entire set if a test fails. Or, you want to cherry-pick the entire set to another branch. They serve as one logical unit. But if you for example care about the decision-making process that lead to that final code change, you can see it by revealing the "inner history".
- imiric 5y agoSo groups would be just named commit ranges? I'm not sure I see the appeal if it's already possible. The article also seems to imply that there's one "right" way to merge branches and that teams should stick to one approach. I disagree. I use all 3 approaches whenever it makes sense: merge commits for large PRs with more than 1 commit where you want to preserve the history of the changes, squash+merge when the history is messy (usually after code review) but the change itself should be atomic, and rebase when the history is clean, though I mostly reserve rebasing for smaller single-commit PRs where a merge commit would just add clutter. I also disagree that Git is this flawless piece of software we can't improve upon. It regularly fails to do fairly trivial merges automatically, forcing me to manually fix conflicts, or use `rerere`. Ideally my code versioning tool would understand language semantics and be as maintenance-free as possible. Git is nowhere near this and requires quite a lot of familiarity and hand holding to work as the user intended. The amount of time and effort spent understanding and using it properly is difficult to quantify, and it's still a tall hurdle for new developers.
- deleted 5y ago[deleted]
- buck4roo 5y agoEmphatically agree. The git cli UX is terrible, cryptic, and forces one to think way too much. The number of GUI tools that wrap the git cli should tell us all something. I Mercurial. It - manipulates the identical data structure (the DAG) - interops just fine with git (thanks hg-git plugin!) - its cli manages to use common sense verb names, by default, for all its functions - includes no unnecessary concepts/models (read: git's index)
- zck 5y ago> [Mercurial]...includes no unnecessary concepts/models (read: git's index) As someone who stubbornly uses mercurial for all his code, git's index is the single greatest feature that git has over mercurial (not counting the Magit interface). The index allows me to _incrementally_ build up a commit. I can go back and fix things, add and remove things from the index, and only when I'm ready, commit. In mercurial, I have to hold so much more state in my head about what is ready to commit, what needs to be fixed, and what is code that needs to be reverted. And `hg commit -i` is nice, but is not a replacement for the index. Git's index allows me to add hunks, then stop, go to lunch, review the status, remove some bits, add more, then commit. I'm told that Mercurial's queues feature would support this, but I find it incredibly non-ergonomic, and I can't quite figure out how to use it as an index replacement.
- raziel2p 5y agoI use squash merge and make sure each PR is small enough to justify being just one commit. Big things which are too big to fit in a single PR can be tracked in other ways, such as mentioning a Github issue number or project management issue ID in the commits. Individual commits on a PR/feature branch are useful to check what's changed since the last review (I silently despise developers who force-push their rebased commits when fixing things, making it basically impossible to re-review). I just wish it was easier to detect locally whether my development branch has been squash-merged so I could script the deletion of them.
- fiddlerwoaroof 5y agoIn theory, you could implement commit groups already in one of two ways: objects in a special ref that are just lists of commit hashes (tree-style) or a branch where every commit has, in addition to the last HEAD of the branch, all the other commits in the group as parents.
- fiddlerwoaroof 5y agoHere's a demo of this idea: https://github.com/fiddlerwoaroof/git-group-demo https://github.com/fiddlerwoaroof/git-group-demo the network graph shows what's going on: https://github.com/fiddlerwoaroof/git-group-demo/network https://github.com/fiddlerwoaroof/git-group-demo/network
- neolog 5y ago> Under the hood, all the commit really says is: > Merge: 8 6 > So it tells you that these two parents have been merged together, but it doesn’t tell you which one used to be main. You might guess 8, because it’s the leftmost one, but you don’t know for sure. Why don't I know for sure it's gotta be the one on the left?
- cesarb 5y ago> Why don't I know for sure it's gotta be the one on the left? Because of fast-forward merges. It will be the one on the left if you, as expected, were on the master branch and merged the feature branch ("git checkout master; git merge feature"). But if you were on the feature branch, merged the master branch into the feature branch (usually, this is done to resolve conflicts), and then went back to the master branch and merged the resulting feature branch into it ("git checkout feature; git merge master; git checkout master; git merge feature"), it will be a fast-forward merge: no new commit will be created, and master will point to the merge commit which was originally on the feature branch, which is going on the opposite direction as you would expect. The solution, as others have already mentioned here, is to do all merges to master as non-fast-forward ("git merge --no-ff feature"); that gives a consistent order to all merge commits on the master branch, and the end effect is the most similar to the "grouping" feature OP wants (if everything on master are these non-fast-forward merges, the difference between one merge and the preceding one is that "group").
- neolog 5y agoThanks. - It's still ok to "git-pull --ff=only", right? - Is it possible to enforce this at the CI level?
- wizzwizz4 5y agoYes to both, though I don't know how to enforce it. (A push hook would do.)
- rusebor 5y ago> which is going on the opposite direction as you would expect. It looks like a bug which should be fixed. Git should create a merge commit when it sees that "the direction" changes.
- stolee 5y agoThat history that looks tangled and awful would look a lot better if the commits were sorted by `--topo-order` instead of `--date-order`. That sort “groups” commits that are in a single line of history.
- Quenty 5y agoAzure DevOps has this concept, it’s called “semi-linear merge” where it will rebase your PR on top of the branch being merged into, but then create a 2 parent merge commit with the PR comments and text to merge the content, letting you easily reconstruct what changes were made in one PR, while also preserving commit history and keeping the history clean overall.
- Jasper_ 5y agoThis is what GitHub used to do, before they changed it to the squash model.
- kibwen 5y agoEmphatic agreement, this is something I've wanted for a while. For the purpose of history management/traversal (reverting, bisecting, or just understanding) you want certain code changes to be atomic, implying that they should all be understood/tested/reverted together. But for the purpose of code review you want something more granular and less monolithic, so that a single reviewer can more easily understand a large change, or so that review can be more easily divvied out among certain code owners. Currently getting all all of these properties requires decomposing the commits during the review phase and then squashing before merge, but this is a bad practice because now no reviewer has actually signed off on the code that's getting merged and you're just hoping that nobody's slipping any last-minute or malicious changes in during the squash.
- tomsmeding 5y agoAgreed; however, since this is HN, I'd like to suggest that it should be totally doable to improve on the squashing workflow using tooling. Programmatically it's easy to verify that the signed-off commits induce the same diff as the squashed commit; they're either equal or not. Then, if the interface where signoffs are registered (e.g. github PR) enforces that all PR's are signed off while allowing a squashed, un-signed-off commit if it has the same diff as a signed-off commit, then you can squash at will. Optionally you could also require that the signers additionally sign-off the final commit, under the tool-provided guarantee that the diff is identical.
- secondcoming 5y agoIs it not standard practice to first merge 'master' into 'feature' before you merge 'feature' into 'master'? If 'master' has changes that are not in 'feature' then 'feature' is out of date, testing probably needs to be redone. It also means any merge conflicts are resolved in the 'feature' branch. If 'feature' is a long lived branch then is should merge 'master' on every release anyway. If your weakest git user cannot revert easily then you're in trouble. Enjoy being on call 24/7 otherwise. Reverting is more important than committing. I genuinely don't understand why people care about git history so much. I've never needed to look at it in 8 years of using git.
- NBJack 5y agoGit history plays a critical role in code forensics, particularly in large code bases (or places where you may have a large number of potential authors). I. E. 10 commits just went to production from 3 different teams on one service. Something breaks a few hours later; was it one of the 10? Was it a corner case in something much older? Or was it someone's feature flag going live? If you deal with a service that has been matiained for a few years, this is also an excellent way to figure out what was done why and when. Or figure out if a well meaning rebase accidentally clobbered a critical piece of ancient logic. Or determine who the heck owns something when you realize it's time to split up a larger service. The list goes on. Note git history plays directly into git blame too; it can be an excellent tool in the right circumstances.
- Noumenon72 5y agoFor stuff like "this line doesn't make sense next to this other line. Why was it added?" Sometimes a line was deleted between them, sometimes it was a bad merge, sometimes the rest of the commit tells you "oh, it was added to make the Foobar work." I have allocated some of the valuable left-hand-only keyboard shortcuts in my IDE to searching Git history. It tells you the "why" when the "what" doesn't make sense, and the "who" when git blame shows some reformatter.
- roland35 5y agoI will admit I am always afraid to lose my changes if I squash! Maybe I should try making a new temporary branch before squashing to give myself peace of mind.
- sopooneo 5y agoI used to have that fear also, but after playing with reflow a bit and seeing how you can get back to almost anything, I’m more comfortable.
- larusso 5y agoI’m one of the people who strongly advocates the squash merge. My PRs are also single commits most of the times with the PR body as the commit message. That is a hidden gem of GitHub, if you open a PR with a single commit then GitHub will use the commit message as the description. The reason why I prefer squash commits is not only the linear history but also the fact that I’m simply not interested in the sausage making process. If a PR becomes so big that it would need multiple commits than I request smaller patches. But I also see that this heavily depends on the team size and general setup. But I use squash PR ever since it was introduced in GitHub. Before I manually rebased the feature branches to have a clean merge.
- sopooneo 5y agoSincere question: does a “squash merge” implicitly include a rebase as well when the merge target has diverged?
- jbrot 5y agoIt means using `git merge --squash` which performs a normal merge but then instead of adding a merge commit, it just makes a single regular commit with the changes.
- richardwhiuk 5y agoIt's equivalent to rebasing, and squashing into a single commit. It's also equivalent to a merge commit, and then only keeping the diff from the merging in branch. So it's sort of a half way house, and sort of the worse of the both worlds.
- larusso 5y agoYes it has it up and downs. But it also helps me and my team to enforce smaller patches since they land as one anyways. And other teams in my company follow the open PR and develop the next 2 weeks on it and merge in full. There is so much garbage in all these commits no one ever wants to get back to. Good luck bisecting on of these histories.
- ufo 5y agoIn my organization we kind of do this. We use one merge commit per pull request, without squashing. However, we also rebase before merging, which results in a commit graph that looks like a cactus: o-o-o o-o o-o-o / \ / \ / \ o-------o-----o-------o-->
- masklinn 5y agoSure but that's not really helpful, the only thing it does is avoid breaking history visualisation tools which tend to deal very badly with "wide" histories. For instance one of the biggest annoyances with git is it's a pain in the ass to find the the merge of a commit into the mainline (aka the next child with more than one ancestor… probably), which can make it difficult to go back from a commit to a PR unless it was a single-commit pull request.
- Hello71 5y agohttps://github.com/mhagger/git-when-merged https://github.com/mhagger/git-when-merged edit: also https://stackoverflow.com/questions/8475448/find-merge-commit-which-include-a-specific-commit https://stackoverflow.com/questions/8475448/find-merge-commi..., and also github shows this (but only for github PRs, not other merges)
- nemetroid 5y ago> Sure but that's not really helpful, the only thing it does It encodes the necessary information in the commit graph, without introducing a completely new concept (commit groups). It’s true that Git doesn’t give you the tooling to get that information out of the box, though.
- masklinn 5y ago> It encodes the necessary information in the commit graph A bog-standard merge already does that.
- rzimmerman 5y agoI also prefer this method - rebase and force a merge commit. It’s pretty much the grouping functionality that the author wants. You can tell a short story or break a merge into a couple parts, and bisect + revert work. You can also link each merge with a merge/pull request and a ticket. Also, an occasional quick fix commit to master works fine and makes sense. Sometimes a merge without a rebase makes sense as long as it doesn’t make the graph too confusing. Different workflows work for different teams, but I like this one.
- everyone 5y agoI was disappointed when I learned that git doesnt remember which branch a commit was made in. cus, Each feature = one branch Each little change = one commit It's annoying that they throw out half of that info.
- cerved 5y agogit forgets nothing. A branch is just a reference to a commit, that reference goes nowhere unless you delete it
- ghoward 5y agoNot GP. I may be wrong here, but I would argue that git does forget something: it forgets where the branch reference used to point when a new commit is made on that branch. If a commit has more than one parent, that means some information is lost because it has to guess which parent the branch reference came from.
- astrange 5y agoThat info is in the reflog, but it will be GCd eventually.
- cerved 5y agoafaik, only merge commits have two parents. Then the source branch would still point to the head of that branch. Furthermore, without having checked, aren't merge commits deterministic in the order of references? I wouldn't be surprised if this information isn't trivially available in a porcelain command but more surprised if it's lost
- ghoward 5y agoIf a branch is just a reference, then how that reference changes over time will be lost. As astrange says, that info will be in the reflog, but the reflog is subject to GC. Once a GC happens, that info is forgotten.
- agshew 5y agoThe idea of commit groups makes me think of Linux kernel style patch series and https://github.com/git-series/git-series https://github.com/git-series/git-series
- emodendroket 5y agoI started using the convention of prefixing commit messages with the ticket they're addressing, which I think is actually pretty helpful. Makes it way easier to do interactive rebases too.
- cerved 5y agoin my personal repos I follow the convention to prefix add/mod/del/fix/sty: to each commit to indicate whether it adds, modifies or deletes the API or whether it fixes or changes the private interface, or if it merely changes stylistic elements (ie no changes to functionality). This helps me quickly understand how each commit affects the whole
- derriz 5y agoThe author identifies the problem which I think is a fundamental failure of the git model which is that commits aren't associated with branches. But proposes a different solution. I wonder why they didn't decide to attach a branch identifier to each commit. This would solve the problem as I see it as you could truly view a branch history; typically for example you'd be asking for logs of the "master" branch history. The topological view can help but the lack of notion of a branch as anything but a pointer to one commit means you effectively do loose history unless you go for a burdensome tagging scheme.
- zeroimpl 5y agoBut commits change branches. None of the commits started on the "master" branch, they started on some developer's branch (which might also be called "master" in a different repo, but is still separate).
- derriz 5y agoI'm not sure I understand your point? Say for example, I'm looking at a freshly cloned repo. There's a first commit and most-recent commit on master - I can identify them with git-log. The problem is that I cannot view the path of commits between these two if I'm only interested in the commits made when the current branch was master (which is generally the case unless I want to drill into a feature branch). Disallowing merges makes the problem go away but that removes a lot of options in terms of work-flow.
- jhardy54 5y agoWould `git log --merges` solve this? Assuming you use a merge-based workflow this would show only merge commits without any of the details of each individual commit from the merged branch.
- zeroimpl 5y agoI don't follow - If you are on a freshly cloned repo, none of the commits were made when the current branch was master, they were made on another user's git repo before your repo existed.
- infogulch 5y agoI agree with the author's sentiment. The way this problem is typically framed is as a dichotomy between preserving a "true" history of what really happened on the micro/commit scale VS presenting a "clean" history that makes the story of the change easy to follow on the macro/PR scale. This is a false dichotomy. I'm greedy, I want BOTH. Give me story mode when I'm just browsing the repo, but offer me the option to switch into commit-by-commit mode when I want more detail.
- andy_ppp 5y agoI've often thought this too, you shouldn't have to rewrite i.e. lie about what happened. Git history ideally should be completely immutable but there should be a view that tidies up what happened for those that like to see individual features/bugs/hotfixes all listed in history in a nice way. I don't like the name thought, commit groups seems odd, I prefer feature view or something else. The reason is commit groups sounds to me like groups of people who are allowed to commit.
- infogulch 5y agoI want to be able to preserve two parallel commit histories: one where the the commits are ordered by time, and another where the commits are ordered by 'story'. Git could cryptographically verify that the end-states of the two histories are identical, and allow me to alter the storied history at will (shifting hunks between commits, splitting/combining commits, reordering commits etc), where during merge both histories are preserved. I don't really follow your naming critique though. "commit groups" seems like a fine name, they are groups of commits. What you describe I would call "committer groups".
- dllthomas 5y agoSomething like --date-order to view commits chronologically vs --topo-order to view them topologically sorted?
- nine_k 5y agoWhat is your use case? How do you develop so that your story does not belong to one (or more) feature branches where it can be held, unmixed with other stories? Can your story continue through multiple merges to the main / release / whatever branch(es)? I'm asking totally unironically; every company's flow may be different, and for good reasons which I'm oblivious about. So I'd gladly read if you had time to explain.
- cerved 5y agoI'm not sure I appreciate the point the author is trying to make because it sounds like what they want is a merge commit
- sakisv 5y agoI think most of the author's pains could be implicitly solved by using tags on merge. That way you maintain a linear history, you get clear marks of when each pr was merged and you can see what happened in between. The obvious downside here is that you'd need to add yet another step in your process and come up with a meaningful system for this.
- eeperson 5y agoIf you use the default merge messages, can't you tell which was the branch that got merged? The second parent is the branch that got merged and its name will appear in the commit message on the merge commit. This is probably something that you could infer most of the time.
- joshka 5y ago--log ?
- eeperson 5y agoWhat command is that flag intended for?
- joshka 5y agogit merge
- eeperson 5y agoGit will provide you with a default message for git merge without specifying any flags. This message includes the branch being merged. I don't think there is support in git to view history with the branches being marked explicitly. However, you can get something similar with: git log --pretty --oneline --graph --topo-order That should at least group commits roughly by branch. Did that answer what you were asking?
- thrower123 5y agoAny workflow that alters history is dangerous. Just merge things normally, and don't get fancy. If you want to futz with stuff and squash commits and rewrite commit messages because you didn't write good ones on a feature branch, fine, whatever makes you happy. But just merge to master, don't rebase.
- cube00 5y agoThe downside if you don't rebase your branch is you end up with a merge commit with two parents with independent commits on both sides which makes bisecting more of a challenge then if you had a linear rebased history.
- theknocker 5y agoSo like some kind of separate sequence of commits that can have its own name.
- lloydatkinson 5y agoYes this would definitely be a way to shut up the “squash merge all the nuances of all the commits for this feature into a single commit called “implement feature XYZ”” crowd.
- jefftk 5y agoYou can do this today in standard git with https://www.davidchudzicki.com/posts/first-parent https://www.davidchudzicki.com/posts/first-parent Summary: every feature is merged with 'main' as the first parent. Then, whenever interacting with history, you tell git you only want it to consider --first-parent
- kevin_b_er 5y agoThe author makes the argument that 'first parent' being the original branch is a mere convention. And he's right. If someone does the merge while checked out on the feature branch, then commits it _as_ the master branch, then the first-parent concept breaks.
- thrashh 5y agoBut that problem is easy to fix with 0 disadvantages: Don’t do that. Don’t do it for the same reason that you have a convention of useful commit messages.
- ianlevesque 5y agoI masquerade as proficient in this field and I'm pretty sure I've done that just by accident with git a few times. Assuming any developer on your team is much better than monkeys on typewriters when it comes to git will lead to disappointment.
- exclipy 5y agoMake a precommit hook that enforces this. Done.
- Groxx 5y agoThis only enforces it where you have the hook installed. And it cannot be pre-installed on people who have newly cloned the repo. Which makes it nearly useless. Not totally - the people who know about it benefit - but it's extremely far from safe. The only way to really enforce this is to add this kind of thing to your "main" remote repo that everyone pushes to.
- toomanybeersies 5y agoIn principle, I agree with the author. Although I don't think git needs group commits to achieve this functionality. My preferred workflow for the past couple of years has been to interactively rebase and squash/fixup! the commits so that each commit represents a functioning state of the code, which more or less achieves the same thing as what the author wants. However, this approach only works if all the developers on a project buy in to this philosophy. As much as I dislike squash and merge, it's better than the alternative of trawling through a git history with dozens of "WIP" and "Fix tests" commits and janky rebases/merges.
- nooyurrsdey 5y agoI disagree with how difficult merge commits are. It's not something to filter out in your view - it's a representation of an actual change made by combining two different versions of a document/code/etc... They are valuable indicators in history. Furthermore services like Github add valuable valuable comments like the PR number that was merged.
- deleted 5y ago[deleted]
- EugeneOZ 5y agoI didn't get the last bit: why author can’t write meaningful commit messages with the merge strategy?
- stormbrew 5y ago> So it tells you that these two parents have been merged together, but it doesn’t tell you which one used to be main. You might guess 8, because it’s the leftmost one, but you don’t know for sure. (Remember, branches in Git are just pointers to commits.) The only way (that I know of) to be sure is to use the reflog, but that is ephemeral: Git occassionally prunes old entries from reflogs. This feels extremely pedantic to me. There are certainly workflows that produce this confusion, but the most common ones definitely don't. For the most part, in especially most github-based flows, the 'left-most' (aka `git log --first-parent`) history of the main branch is precisely the history of the main branch, and the "commit groups" are the divergent "right" parents. Can someone do something that temporarily breaks this? Sure. People `git pull`ing with divergent changes at least used to litter projects' histories with this kind of nonsense. But it's not terribly likely to make it into your main history these days if your upstream repo has a 'protected' main branch, which is so normalized at this point it ought to be considered the default state of affairs. It seems like maybe the thing the OP really wants is just for the branch name at commit time to be stored as metadata in the commit. That would maybe help with pulling out intentions while looking at history. Also, Mercurial had a kind of 'hard branch' feature that also might have resembled what's desired here, but as far as I can tell most users of mercurial found it more frustrating than helpful and used plugins that provided looser kinds of branching.
- quickthrower2 5y agoAnother way is to have a concept of the “start” of a branch. If when you create a branch it remembers where it started from then the commits on the branch after that point form a natural commit group. If you need finer commit groups you can have more branches.
- latortuga 5y agogit merge --squash on the command line will do this. It automatically dumps all your beloved handcrafted commit messages into a single squashed commit.
- bonestamp2 5y agoIt's not what the author was talking about, but the title reminded me of perforce changelists. I wish git had something similar. Basically, it's a way to organize and group unrelated changes until you're ready to stash/shelf/commit them.
- theodric 5y agoI wish git had a function to dump a checksum that I could call on with the command 'git sum' Please, devs
- koolba 5y agoIsn’t that just the commit hash of the head? Or do you mean a hash of the hashes of all your heads?
- macawfish 5y agoThis reminds me of Pijul and Darcs, which are patch based VCS's, although I'm not sure that's quite what the author of this article has in mind.
- e9 5y agoWhile GitHub is not Git, it offers this by having concept of a pull request/review that can be merged as single commit but kept as multiple commits in the review history. What if git incorporates this concept as a core feature?
- kovac 5y agoTeams I've worked with lately use squash merge with the PR summary set to the issue number and issue summary from the issue tracking system. So, there are links to the issue and the PR from both systems if we need to track down why something was done. Seems to work well for us. I personally wouldn't want to see 15 commits to the main branch from one PR regardless of how descriptive the commit messages may be.
- HALtheWise 5y agoMy company previously had a beautiful (but unconventional and much-misunderstood) solution to this issue. To merge a feature branch into master, we would _first_ create a squash commit consisting of all the changes with the commit text containing the review message and a link to code review. Immediately after, we would _also_ add a merge commit that referenced the original feature branch, but resulted in no changes to master. This meant that log/blame would default to showing the high-level summary of each review, but the git commit graph still has the full gory history if anyone needs to look at it. More importantly, you could safely start developing on top of someone else's unreviewed changes and git would correctly be able to track who made what changes, in a way that breaks badly with a standard squash or rebase workflow. To view the "simplified" linear history, you run "git log --first-parent --no-merges", which unfortunately doesn't have a config option to set as default. Unfortunately, we lost this workflow when we moved over to GitHub, and now git blame is surfacing everyone's broken wip commits because we've stopped adding the high-level summary squash commits.
- deleted 5y ago[deleted]
- nixpulvis 5y agoWait isn't a "commit group" just a branch?
- tuxie_ 5y agoI see lots of comments here on how important it is to preserve "history of what really happened", arguing that cleaning up the history "is a lie the same way that people who wear makeup are 'lying'" and that "someone might learn something from it". I feel that it's quite over the top. Nobody goes to the commit history to "learn programming" (or at least you should not) and if you did, it would be so confusing to see things added in a way and changed back 2 commits later because it didn't work. The code is just half the story, it needs context, it doesn't represent the train of thought behind the changes, that's only in your head. If you want to document what didn't work write a document where you explain the different approaches you took, why they didn't work and what you did at the end. That really is super useful. Just keep the history clean, if you ever need to revert a change you will be grateful you didn't add many changes to 1 commit or didn't change the same code in 5 different commits throughout the PR. Keep the code working at each commit, if you ever need to `git bisect` you will be grateful you did.
- bad_username 5y agoThe most important benefit of preserving the history is being able to go to an exact state of the program in the past. Pinpointing the commit that introduced a regression is often by far the quickest method to localize the problem. And it is impossible when the history is rewritten, and consists of snapshots that were never even ran. This benefit is much more important than having a visually pleasing history. And you can always get a visually pleasing history by adding a few flags to git log.
- TomSwirly 5y ago> The most important benefit of preserving the history is being able to go to an exact state of the program in the past. No one's talking about ever getting rid of any commit ID that got checked into `main` or `master`. We're talking about getting rid of commit IDs that only ever existed on one machine and only during development. From my reflog, I see this commit ID: `21b9f2e HEAD@{28}: commit: Fix and instrument nstray URL problem` No one needs to know about my typo - ever.
- lucideer 5y agoI feel like, as with many things, this is something that git "has", but that interfaces/uis for it just handle poorly. Maybe "poorly" is unfair as this would be relatively complex to implement in a way that has good simple intuitive ux. But from the perspective of anyone using vcs daily it does seem an obvious want, so I'm surprised it hasn't been done well yet.
- joshka 5y agoyeah, if this was git merge --feature foo (equivalent to git rebase main foo ; git switch main; git merge --no-ff foo) it might be nice, but then again, making custom git scripts is pretty easy.
- maratbn 5y agoAs pointed out in other comments, git does allow this by using `git log --graph` and 'merge --no-ff'. However, it is also necessary to use git "empty" commits as the first commit of each "group" to prevent confusing output from 'git log --graph' when nesting and sub-nesting groups of commits. Here's an example of doing this -- https://github.com/maratbn/test_nested_sub_groups_of_commits/tree/master--w-empty-commits https://github.com/maratbn/test_nested_sub_groups_of_commits...