19 ms·
I kind of like rebasing
- Carrok 2y ago> Some like to rebase, while others prefer to keep the disorganized records. Keeping disorganized records is the only thing you can say in favor of merge commits, and I'm unconvinced that's a positive thing to begin with.
- jaredsohn 2y agoI think the argument against rebasing is spending time polishing a PR to have a cleaner history for one feature that will maybe get looked at during review (rather than the final output) vs also making a PR for a second feature during that same time. And you can eventually have github squash for you anyway.
- yencabulator 2y agoRebase work resulting in atomic commits != squash
- lesuorac 2y agoWell disorganized records can still be very useful. If you're trying to figure out where a bug came from it can be helpful to bisect through all the commits. If you bisect down to 40 file change that's going to be a pain to continue bisecting. However, if you can bisect down to say 5 changes where your bisection fails and 4 of them are because the app fails to build and the 5th is because that's when the bug was introduced that can be very useful.
- deleted 2y ago[deleted]
- joe_fishfish 2y agoYou can’t do stacked PRs without merge commits, not unless you really like conflicts anyway.
- seadan83 2y agoI have never seen stacked PRs work that well in practice. Two reasons: - Namely there would be review comments on the first PRs that then cause a cascade of merge conflicts in the follow-on PRs - Somehow reviewers never seem to like the stack of PRs, my experience is they always react with disdain and/or confusion. There is the counter-question too, why not stack commits cleanly? A third reason against, not a good reason, but for many developers Git is super difficult (IMO largely a skill issue, not taking the time to learn basic tools that they need everyday; otherwise I have no clue why software developers do not learn their IDEs and VCS tools very well). Stacking PRs requires some Git skills, a simple feature-branch workflow can be a challenge for many.. Ultimately, I think the solution to stacked PRs is to change review policy to "ship/show/ask": https://martinfowler.com/articles/ship-show-ask.html https://martinfowler.com/articles/ship-show-ask.html In other words, if someone is skilled enough to do a set of stacked PRs, the team likely benefits by letting that person merge the stack on their own when each bit is ready and do a post-merge review instead of pre-merge. (Side-note, my unsolicited perspective: I'm personally convinced that the benefits of linear history is a magnitude more important than all the other peeves & nits combined between merge vs rebase.)
- edfletcher_t137 2y ago> - Somehow reviewers never seem to like the stack of PRs, my experience is they always react with disdain and/or confusion. Are people sending multiple branches of the stack for review at once? It should only ever be the "bottom" branch out-for-review at any time. > - Namely there would be review comments on the first PRs that then cause a cascade of merge conflicts in the follow-on PRs This can still happen in the model above of course as you need to make changes to the bottom branch in response to review comments/requests. However, as I noted elsewhere, `--update-refs` is an absolute god-send in those situations: https://andrewlock.net/working-with-stacked-branches-in-git-is-easier-with-update-refs/ https://andrewlock.net/working-with-stacked-branches-in-git-... It reduces a ton of manual work (scaled by how many branches you have stacked!) to one operation.
- seadan83 2y ago
- draw_down 2y ago[dead]
- quibono 2y agoPersonally I am squarely in the rebase team although I'm not completely anti-merge. I find the interactive rebase to be so useful that I pretty much never rebase non-interactively. I wonder if part of the reason the merge flow is more popular (or at least it seems more popular) is because native Git tooling around rebasing isn't the best. In fact doing anything more than the simple reword/squash/reorder (like commit splitting or moving chunks between commits) is abysmal. Magit really shines here and makes it a breeze.
- switchbak 2y agoI think Git's roots show in its lack of DX. But I'll take it over the horror that was SVN and prior tooling. Question: how does Magit compare to GitUp? The latter is my benchmark for complex rebases, but I'd love to know if I'm stuck in a local optima.
- joshuanapoli 2y agoI haven't used Magit or GitUp, but I really appreciate JetBrains IDE automatic conflict resolver.
- quibono 2y agoI've not used GitUp so I'm not sure how much help this will be to you since I can't objectively compare the two. As an example, let's say I want to remove some changes from a commit (and potentially move those into one or more different commits). If I go into the commit and select the chunks I want to revert, I can click `u` and right away I get the revert chunk added into my staging area AND the original chunk added to my working tree. Then I just fix-up the original commit (c F) to remove the unwanted change, and commit the original change - either in a few different commits or possibly just one.
- bigstrat2003 2y ago> I think Git's roots show in its lack of DX. But I'll take it over the horror that was SVN and prior tooling. This statement really confuses me. SVN was so much easier to use than git. It was incredibly straightforward: make changes, commit, done.
- deleted 2y ago[deleted]
- nailer 2y agoInteractive rebase is indeed great, but: # Commands: # p, pick <commit> = use commit # r, reword <commit> = use commit, but edit the commit message # e, edit <commit> = use commit, but stop for amending # s, squash <commit> = use commit, but meld into previous commit # f, fixup [-C | -c] <commit> = like "squash" but keep only the previous ...the CLI git text-document rebase UI is awful. Better command-line rebase UIs are available, or in Fork, I just select a bunch of tweets, right-click, and squash into parent (or use the https://git-fork.com/images/interactiveRebase.jpg https://git-fork.com/images/interactiveRebase.jpg where necessary). If someone complains that CLI git is somehow more pure than using a decent GUI, ask them to rename a stash and time them.
- pluies 2y agoIs it that awful? Each option is nicely explained, and the documentation is exactly where you need it, when you need it. I personally found it extremely helpful during my first interactive rebase, and still give it a glance from time to time when I forget the difference between squash and fixup.
- quibono 2y agoProvided rewording, reordering and squashing (or fixing up, same thing really) are all you need I think you could argue this is true. Trying to do anything else tends to be a bit of a pain. On another note, is it possible not to lose the commit description when trying to split a commit? I'm talking about 1) marking commit as `e` to edit it 2) git reset HEAD~ to move back 3) split the change however you want 4) commit again whenever I do it I always lose the original commit message. I'm not sure if it's me being stupid or if there is just no simple way to do it.
- switchbak 2y agoI had a colleague (smart guy, lots of impressive Ivy League creds after his name) who just _insisted_ that rebasing was evil. There was simply no way to communicate that: - I can rebase all I want in my own private repo - Rebasing is fine if no one else thinks they can depend on your branch's history - You obviously don't rebase master (!) or a branch that you'll collaborate on (not without proper warning at least). I've seen this attitude more than a few times, and I think it's fear born of ignorance. I just don't get the inability to consider a different perspective. Edit: formatting.
- recursive 2y agoNot only ignorance. I don't generally use rebase myself. This is after having some experience with it. I recently had to help a junior un-wedge his local repo after an attempted rebase went haywire. I reset to the previous commit and replaced the rebase with a merge. The rest of the lifetime of the branch was uneventful. The problems happened because rebasing changes the identity of commits. When merging that result, commits that have previously been merged create conflicts as they now need to be re-merged under the alias of a different commit hash. If rebasing works for you, I'm not going to try to sell you something. But there are other ways.
- YZF 2y ago`git reflog`
- recursive 2y agoI use this regularly. Mostly to answer one question. What was the name of that branch I was working on yesterday? Or maybe you're suggesting it as a way to unravel a screwed up rebase. I don't know how to do that. But luckily I do know to abort, reset, and merge.
- YZF 2y agoYes, you can recover from a screwed up rebase or virtually any git problem you created via git commands. You find the commit before you rebased and reset to it. One reference: https://stackoverflow.com/questions/134882/undoing-a-git-rebase https://stackoverflow.com/questions/134882/undoing-a-git-reb...
- IshKebab 2y agoRebasing is definitely the better option if you can do it. Sometimes it is just too much of a pain resolving conflicts if you are rebasing a branch with lots of commits and there are lots of conflicts. In that case I normally squash and then rebase. Branches where there's enough history to be worth maintaining multiple commits should - 99% of the time - be separate PRs. The rare exception is when you have multiple people contributing to a branch before it is merged into master, but for obvious reasons you should avoid that when at all possible.
- technojamin 2y agoGit rerere basically solves this: https://git-scm.com/book/en/v2/Git-Tools-Rerere https://git-scm.com/book/en/v2/Git-Tools-Rerere
- recursive 2y ago> Rebasing is definitely the better option if you can do it. A bold claim. > but for obvious reasons you should avoid that when at all possible. Obvious? I do this somewhat regularly and haven't had a problem. I don't even know what the problem is supposed to be. Also, I never rebase. Maybe that's why I don't have a problem? When you rebase, commit A becomes commit A'. This becomes a problem when you need to determine whether a particular commit is an ancestor or not. A and A' have different commit hashes, so the identity of the commit becomes somewhat ambiguous. My workflow is do all development using merge only. When the code review is complete, squash to master. I have found no down sides to this. But I'm not trying to sell it to you either.
- ycombobreaker 2y ago> Branches where there's enough history to be worth maintaining multiple commits should - 99% of the time - be separate PRs. I appreciate that anyone saying this is probably already on the same wavelength as me, but I don't find this to be true for myself. Many times, complex application features end up represented as a series of related, but atomic/meaningful changesets. I want the pull request to make sense as a whole, but expect that code review or audits are easier to accomplish diff-by-diff. I see it like building a recipe. I want to hide all of the false starts, sloppy mistakes, do-overs, and checkpoints, because they are useless from a historical standpoint. But I still may want to publish a sequence of changes that accomplishes something.
- joshuanapoli 2y agoI like rebasing too. When I have any significant change, I usually end up making a mix of clean-up and preparation around my new feature. I like to move the separable parts into separate branches, so that there is less to review per request.
- cocoto 2y agoIn my opinion squashing is all you need. You keep the organic history on the original branch and the clean and easy to follow history on the master branch. Ideal would be to have a “collapsing” commit instead of squashing for ergonomy.
- simongr3dal 2y agoYou sort of get that if you're consistent in working on a separate branch, rebasing, and keeping the merge commit when you finally merge.
- recursive 2y agoBut you can also get it with much less discipline if just go wild merging and doing whatever. And then resolve your master PRs using squash.
- pizza234 2y agoHighly disciplined/structured PRs (with a high rate of atomic commits) merged via merge commit have significant benefits: - easier to read/analyze - have better documentation (more isolated git metadata/history) - are easier to debug (and possible to bisect; it's not possible to bisect a squashed commit). The problem is that it requires a significant amount of discipline (of course, 100% rate of atomic commits is not possible, but high rate is).
- jaredsohn 2y ago>- are easier to debug (and possible to bisect; it's not possible to bisect a squashed commit). In practice, if bisecting indicates a commit caused the problem you can narrow it down further by checking out that branch and investigating further within that branch (which ideally isn't too large). Also, if you have a highly structured PR then you may need to be careful to ensure that each individual commit passes CI. At that point you might as well ship each commit via a separate PR. (While in development you can temporarily set the branch for Part 1 as the base for Part 2.)
- fleekonpoint 2y agoI also like rebasing. Sometimes my squashing cannot be completed without manual intervention, so I'll do a squash merge into a temporary branch instead: git checkout main git checkout -b squash-branch git merge --squash [branch-to-rebase] At this point I usually git diff the two branches as a sanity check before merging back into main: git diff [branch-to-rebase] git checkout main git merge squash-branch I am normally able to squash rebase 99% of the time using git rebase -i main, but doing a git merge --squash into a temp branch has saved me a lot of hassle over the years.
- deleted 2y ago[deleted]
- elijahbenizzy 2y ago100% team rebase -- I think the fear comes from "rewriting history", which sounds scary until you realize that git is entirely immutable data store (through the API at least). Blockchain for the win! I find merging to be extremely tough to work with -- I don't think I actually got good at git until I learned to rebase entirely. Also, cherry-picking (effectively an atomic rebase-type) is underrated.
- pdonis 2y ago> git is entirely immutable data store Not entirely, since git can automatically garbage collect commits that aren't reachable.
- edfletcher_t137 2y ago> I find merging to be extremely tough to work with -- I don't think I actually got good at git until I learned to rebase entirely. > Also, cherry-picking (effectively an atomic rebase-type) is underrated. This this this, all of this. I never really "got git" until I finally committed to learning how rebase works. +1 to cherry-picking. Also patch-add (`add -p`).
- notJim 2y agoStep 3 can be simplified slightly be doing git fetch && git rebase origin/main. No need to check out the local main.
- blcArmadillo 2y agoOr: git pull --rebase origin main
- rednafi 2y agoTIL. Thank you.
- xyzzy4747 2y agoIf you're using complicated git commands, you're probably doing the wrong thing.
- quibono 2y agoI guess it depends on what you mean by a complicated command.
- kkfx 2y agoRebasing is a way to cleanup when a project have a useless history because of too many small commits, badly described and so on. A dangerous way, but still a way. The issue is another: git does next to nothing to handle forks. We can cherry pick some commits, but there is no easy way to state "we have a project that a certain point in time diverge, keeping some common base, that need to be kept in sync, ignoring the fork specific changes". This led to long and manual three-way merges. No extra help.
- AceJohnny2 2y agoAh! My people. I, too, much prefer a rebase-heavy workflow. It allows me to both have a dirty "internal" history and clean up for publication. As a side-effect, it also makes me comfortable having a mostly linear-history for what I publish, as opposed to a many-branched, merge-heavy one, which I dislike, and makes history confusing. I reject the argument that a no-rebase, merge-only history "preserves the true history of how commits were created", because I believe that is irrelevant. What is relevant is what the tree looks like once the merge (or rebase) lands. Should a merge conflict arise, in a rebase workflow the conflict resolution is folded into the rebased commit, so it looks like it was fine all along. In a merge workflow, the fix is in the separate merge commit. In both cases you still have to handle the merge conflict. And in my opinion it is not significant for the merge conflict resolution to be separate from the original commit itself because, again: what's important is the final state of the repo.
- AceJohnny2 2y agoI'll add what should be obvious to any seasoned git user: rebase is only possible for "private" commits. If the commits were published, then merge is the only solution, because otherwise with a rebase you will "change (git) history" and break people's repos that have yours as upstream. I recommend reading this 2008 exchange between top Linux developers learning to use git, and Torvalds's... characteristic language when talking about rebasing a "public" repo: https://www.yarchive.net/comp/linux/git_rebase.html https://www.yarchive.net/comp/linux/git_rebase.html (I'm putting "private" and "public" in quotes because they're really on a spectrum)
- ruraljuror 2y agoI like your point. The exception is if the project you work on is itself downstream, in which case maintainers will rebase those “published” commits, probably employing the same technique they use to keep their local development branches up-to-date with the downstream project.
- MrDarcy 2y agoIn practice it’s fine to rebase and force push to your own published branch, even when it’s an open PR. Just mark it draft or otherwise communicate when it’s no longer a moving target.
- mrinterweb 2y agoAtomic commits can be great. I really prefer to see intentional atomic commits with meaningful messages than 20+ files changed with a commit message: "Feature X". I am 100% onboard with devs squashing their "lint fix", "test fix", "whatever minor fix to get CI working", "generally meaningless commit to cross the finish line". Also, if devs are working on something they check in a "WIP" commit. It is great if you smash your WIPs into a single meaningful commit. These manual squash strategies require some discipline to clean things up. I think the "squash branch to a single commit" merge strategy defeats the purpose of atomic commits. Of course devs will be bad at atomic commits if the commits will inevitably smashed to a single commit. IMO squashing branches on merge is a bad version control strategy. I love it when commits are intentional. One rule I have for any rebasing is, when there may be more than one person using the branch, no more rebasing that branch.
- tkiolp4 2y ago> Atomic commits can be great. I really prefer to see intentional atomic commits with meaningful messages than 20+ files changed with a commit message: "Feature X". The most valuable “feature” of git for me is the “single commit with 20+ files changes”. I explain: I have landed in a new codebase, and now I need to add a new feature that would include perhaps a migration and adding a “usecase” and perhaps a “controller” and the corresponding tests. As usual, things are never clear in new codebases (depending on the library/framework used, one might need to add routes to a main routing file, or perhaps touch some configuration yaml file to whitelist the newly introduced endpoint, or perhaps a changelog needs to be kept updated whenever a migration is introduced, etc.). My point is: if I can git blame a line of code of the codebase that’s doing already more or less what I want to introduce, I want to see ALL the files that were touched as part of that change. It’s a lifesaver.
- deleted 2y ago[deleted]
- mrinterweb 2y ago> How many years have you worked in the software industry? Professionally, 21 years. Seems like you're implying that someone with an opinion that is different than your own is not experienced.
- jaza 2y agoI just git commit --amend and then git push -f origin feat_branch all my incremental changes. Saves me having to think of even one word commit messages like "typo" or "renaming". And saves me having to do an interactive rebase later (which basically has the same end result as git commit --amend anyway). Nobody on my team cares about those incremental changes, including me.
- mnahkies 2y agoThis may be rose-tinted glasses, but I was fine with merges with Mercurial / https://tortoisehg.bitbucket.io/ https://tortoisehg.bitbucket.io/ but subsequently using git (with gitlab/GitHub ) I've been rebase + `--force-with-lease` every time. I'm happy with my current git workflow, but I can't help but feel I'm missing a trick through finding git merge commits so difficult to understand
- juancn 2y agoThe only issue with rebasing is if someone else has checked out the branch and now they have diverged. It's usually a simple fix, but it can get annoying. I tend to checkout branches to do code reviews, when changes are complex a diff is not enough, I want an IDE to help me reason about the code (I sometimes even refactor and try different things just so I can understand the code better, so I can make good suggestions). When I do this, and comment, and the other dev rebases, it's an extra step for me on the next CR cycle.
- kutenai 2y agoI train my team on how to resolve this. Every team member is able to resolve a force push onto a branch they have local. Also, we tend to avoid having multiple people work on the same branch.. so, that's also a thing. If there was a multi-person development effort, then each of those people would have to have a sub-branch of a main feature, and then they would be rebasing their work onto the 'main' feature branch.. which would ultimately be rebased on to dev.. etc.
- rednafi 2y agoNever rebase shared branches.
- kutenai 2y agoI've looked at the "arguments" for not rebasing and reject them. I've never once thought 'oh shit, I wish I had not rebased that'. Keeping things neat in the repo has gained me far more than I ever theoretically lost by some conceptual "loss" of history.
- jauntywundrkind 2y agoGitHub uses the committee date, and the committee date changes with rebase. So I almost always --committer-date-is-author-date. Most people don't and it kind of makes their rebases ugly in GitHub, appear to all have happened at time of rebase, which is obviously no good & useless. Rebasing is excellent. It's a whole suite of tools, unlike merge, which is just merge, for managing history. Rebasing is how I build a sensible history. I should see if there's some way to set --committer-date-is-author-date by default. Also haven't found a way to make git pull --rebase do c-d-i-a-d.
- 000ooo000 2y agoEveryone's got an opinion on "rebase", and IMO you can safely ignore those that conflate: * the rebase command, as a means of adjusting commits * the practice of squashing all commits into a single commit (typically, but not always, via rebase) * the "rewriting of history", whether on public or private branches * rebasing on merge vs. creating a merge commit This article starts by saying they "like rebasing" only to then say >Git rebase allows me to squash my disordered commits into a neat little one Rebase allows this practice but you could just as easily `git reset @~` a few times and then `git add .; git commit -m "My big commit"`. Alternatively the author could just `git add .; git commit --amend --no-edit` throughout the task and end up with the same result. To be fair to the author, they later add that they don't always squash to a single commit, but here I'm talking about "rebasing" vs. commit practices. Rebase is just a tool which allows various practices and it's tiresome seeing the same arguments against this nebulous "rebase", when the arguments are actually directed at practices.
- taftster 2y agoI really appreciate the distinction you're making here. That is, rebase itself is not necessarily either the hero or bane of the process. There are several ways to the "squash my disordered commits" problem, which you've described nicely. I personally use rebase similar to the author, to squash all my noise down to my final intention. But this could be achieved in other ways, just the same.
- bluSCALE4 2y agoI'd make fun of you so hard if I saw you doing that. You'd lose all your comments and have to retype them manually.
- phendrenad2 2y agoGreat, just don't force it on me, or grumble when not everyone on the team does it.
- account42 2y agoUnfortunately for you, working in a team means changing the way you work in order to facilitate cooperation.
- dham 2y agoI don't know why anyone cares about this stuff. You can literally do whatever you want on your private branch. If you want to make your life harder, that's cool. Just squash into the main and call it a day. None of this stuff matters anymore, like it did when I started my career.
- klysm 2y agoI agree you can do whatever you want on your private branch. Unfortunately I think a lot of developers don’t have a solid grasp of what’s possible in private, and more importantly what you should do in private vs. on public branches.
- 000ooo000 2y ago>None of this stuff matters anymore, like it did when I started my career. Explain?
- osigurdson 2y agoThe problem with rebase is it creates a lot of friction when sharing with others. Even if a single dev has two checkouts, it can get confusing ("can I just pull the changes or do I need to reset the branch? - dammit what did I do again? I guess I'll have to review both checkouts history in detail"). Merge based git push / git pull in the other hand, have none of this, thus conceptually much simpler. Furthermore, since pushes must necessarily overwrite (--force), you actually risk loosing work. This is all fine and doable but you have to be "on the ball" / paying close attention all the time thus introducing higher cognitive load. The bottom line is getting work done and making history look good are competing objectives to some extent. There are all kinds of reasons to commit code (I got something working, I want to share something, I need to try this on another machine, etc.). Thus, the only way for commits to appear logical / atomic is to review the current state and refactor it to a logical looking but artificial series of commits. I can't imagine such efforts being useful enough to actually do in most cases. Perhaps even a task better suited to AI. In reality, the PR is the only commit that anyone cares about. Everything else is mostly just noise. Therefore it would be best if the PR was a first class concept in git vs something only available outside of it (i.e. github).
- klysm 2y agoAlways use --force-with-lease.
- rednafi 2y agoThis will only save you if you haven't taken a pull right before pushing your changes to the remote branch. I almost always do this: ``` git pull --rebase main ``` And then push the changes with `git push origin HEAD`. Pushing with `--force-with-rebase` won't save me from this. I usually never rebase a shared branch.
- rednafi 2y agoTwo rules of rebasing that I follow strictly: 1. Never rebase a shared branch 2. Never break rule 1
- 2y ago
- peter_l_downs 2y agoEnforce squash merging to main and move on with your life. Linear history on main, individual contributors can rebase and merge or format-patch or do whatever they want on their PR branches and it doesn’t matter. There are zero downsides to this approach.
- rednafi 2y agoYep. Neither the rebase nor merge workflow negates the benefits of squash-merging to main.
- 000ooo000 2y ago>There are zero downsides to this approach. Squash merge.. zero downsides.. hard to take you seriously.
- peter_l_downs 2y agoWhat are the downsides of enforcing squash-merge to main?
- lolinder 2y agoI use interactive rebase to construct a useful commit history that will communicate intent to future developers. Things like "move a file first, refactor it in a separate commit" make a huge difference when someone's coming around to view the file history later, and a squash merge removes all that information that I've meticulously encoded in the commit history. My preferred workflow on a team project is to have well-crafted commits with merge commits. The merge commits signify the wider intent and link back to the PR in GitHub, while the interactively rebased commits tell the story of the steps to get from point A to point B.
- 000ooo000 2y agoLoss of utility of tools like git bisect, conventional commits, etc. Git blame is less useful when what were individual commits associated with lines are instead rolled up into a massive commit, such that each affected line is now described by a more general commit. It can encourage lazy developers to submit shit commit history in PRs knowing it's going to be squashed anyway, making PR harder.
- breatheoften 2y agoStrongly pro rebase here. I sometimes wish I could require squash merging to main so that history on main is fully linear -- however the fatal flaw with doing that is that it becomes impossible to know from git history whether a given branch has actually been merged to main or whether it was abandoned and left to dangle and rot forever. The inability to observe merge state for a given commit increases the effort required to know whether some given piece of work was merged (or at least requires using mechanisms that are not native to git to make such a determination) and complicates cleaning up old local branches after they are merged. If you use a graphical git client then seeing a brunch of old local branches that are already merged everywhere is noisy and distracting. When real merges are done then can easily write a script to remove all the branches that are already merged to main which helps to reduce noise and maintain better focus and faster navigation.
- AlwaysRock 2y agoI love rebasing. I know a few people who have disliked it when they first started doing it and most of the time its because they would not rebase into their branches often while working. This made for one big rebase at the end which can be a nightmare.
- kwakubiney 2y agoThis is exactly what I do at work everytime. The only issue with this sometimes for me is when i rebase interactively and i have my commit message with all squashed commits. So I do a `git commit —-amend` on the squashed commit and tidy up the mess in the message.
- pseudoramble 2y agoNot too interested into diving into the debate itself, but one minor point I wanted to add to the article where they count the commits to squash and then do `git rebase -i HEAD~n` is that you can replace this strategy with using the branch you're targeting. So if you're working on a feature branch to merge into `main` you can update the local main branch first, then punch in `git rebase -i main` and it'll handle finding all the commits for you. I'm sure there's even more clever ways to do this, as it always seems like there's more when it comes to git. This is just the most intuitive way I've seen so far, and so it sticks in my mind.
- hansvm 2y agoAnd a fairly quick way to do the same sort of thing is `git fetch && git rebase -i origin/main`. You never bother updating `main` because you kind of don't care for the task at hand.
- pseudoramble 2y agoTrue, good point. Makes sense! Thanks for the improvement!
- iamhamm 2y agoI read that as “I kind of like freebasing” at first and thought it was a bit racy.
- NathanFlurry 2y agoOur team switched over to Graphite [1] 8 months ago now. Graphite involves a lot of "restacking" (i.e., rebasing for every commit/branch in a "stack"). No one on our team had used rebasing extensively before this, but it's hard to go back. Similar to the article, the benefits we see are: - Fast iteration with `gt m` (`git commit --amend`) and `gt s` (`git push --force`) - Using `gt restack` (`git rebase` on each parent commit) helps make merge conflicts more transparent in what happened - Commit histories are much more legible I highly recommend giving it a go. [1] https://graphite.dev/ https://graphite.dev/
- stevebmark 2y agoI find merges more confusing than rebasing. At the end of rebasing you just have commits. Merges are commits with multiple parents, which is a confusing concept.
- account42 2y agoMerges are also dangerous because they can contain arbitrary changes (a commit is just a tree state with parent references but the tree state can be anything) but no one ever looks at the merge commit changes themselves.
- krick 2y agoThat's pretty weak defense of rebase. It almost seems like an attempt to promote the opposite. To "squash my disordered commits into a neat little one" is like the only bad and questionable practice involving the word "rebase" which people can rightfully object to. And rejecting that they will usually (unjustly) reject a dozen of other practices involving "rebase". "rebase" does not equal "squash". Using "squash" checkbox in Gitlab is not synonymous to "rebasing". If you actually care about organizing you disordered commits, you can do it in a sane way and use git rebase -i master. That's basically how I work all the time, I don't even try to write meaningful commits first, I even commit stuff I know I must drop later and I commit every little incremental change file-by-file (to make re-ordering commits easier). Then I'll rebase them interactively to review what I did and make several (most of the time) clean atomic commits. Then, rebase is simply superior to making merge commits all over the place, because it... well, "does nothing" as opposed to "makes your commit tree into a complete mess". There can be reasons why you would rather not bother rebasing on a particular project, but if you don't have them (i.e. you just don't have a strong justifiable opinion on that matter), just set [pull] rebase = true, and use git merge --ff whenever possible. Most of the time it doesn't even feel any different and just works.
- overgard 2y agoI feel like squash-merge accomplishes what I want (easy revertibility and simpler history). I'll admit I need to learn it better, but every time I've tried to use rebase I feel like I'm playing with fire and I end up doing silly things like making a backup of the whole folder. I just think the process is unintuitive and somewhat scary, and I don't get the net gain. Like, outside of looking at the last couple days is anyone really spelunking into history that much anyway?
- micimize 2y agoRebasing potentially allows for clean, clear documentation of changeset intent in a way that integrates easily with our existing tooling, at the expense of a potential footgun in highly collaborative scenarios. Ie, if someone forked off your branch or referenced a commit you might break a reference accidentally. So it can be nice, but really depends on the environment you're working in. Gerrit solves the referencing issue by using git notes and maintaining its own ID for changesets across rebases. Without such a system, some seeming benefits of the rebase workflow, like atomically reviewable stacked commits, become fairly awkward. IE, if we want to review commits themselves, but their references get clobbered due to a rebase, that's no good (this was the case a few years ago with GH's rebasing support, maybe improved since). IMO, that we have to make the "rebase or merge" tradeoff at all, or accept the deep limitations of pure commit-based history, is fairly sub-optimal. It'd be nice if more tooling/workflows were built more around notes. I envision someone/some bot going back and annotatinb a range of commits with a note that associates them into some coherent code documentation system, or amends some faulty assertion, links artifacts, etc. That way blame could take us to salient docs or surface behavior snapshot gifs or w/e. From directly within IDEs
- fastball 2y agoThe best solution is to squash messy commits into one atomic commit, and then use rebasing for a clean history on top of that. But I find that squash-merging all the commits from a PR or branch is generally not what you want. And if you have atomic commits, then merge commits generally aren't helpful. As others have pointed out, what matters is when the code was added and what it does, which becomes very clear if you have a linear history without merge commits (but atomic commits as much as possible). If during the development process your commits aren't atomic, that is fine, but then you should make them atomic with squashing before they actually get rebased into main. So for example if I'm in a personal dev branch and I have "messy fix feat A", "fix feat A but better", "even better feat A", and "add feat B", I should just squash the first three into "Improve feat A" and leave the fourth alone as "Add feat B". Then after a PR review or tests or whatever you just rebase into main. Now there is still a clear delineation between my fixes to A and my addition of B, without forcing me to make separate PRs for highly related features. I end up with: - clean history - atomic commits - limited mental overhead when doing quick and dirty commits - not forcing atomic PRs which can be overwhelming
- jaredsohn 2y agoI look forward to the day that I can run a local LLM (for confidentiality reasons) to automatically reorganize commits within my PR. Should be very safe compared to generating code or merging/rebasing other code since it is just changing the grouping of commits and the final code should be unchanged. This would free up developers to spend more time solving problems for the business instead of tidying up code. Could also delay doing this to when somebody is trying to understand the code (during review or later) or doing a bisect.
- danjc 2y agoYour commit history is part of your product, not scaffolding. Well designed commits make a codebase a pleasure to work on and reduce the accrual rate of technical debt.
- jacobr 2y agoAny article about rebase is incomplete without the mention of `git commit --fixup fb2f677`. When committing you usually already know which commit you’re “fixing” so you specify that. Then you run `git rebase -i --autosquash origin/main` instead and the commits are already in the right order.
- account42 2y agoEven when I do know which commit I am fixing I usually don't know the commit hash without looking it up - and doing that takes as long as manually reordering the lines in an interactive rebase.
- dudeinjapan 2y agoDo not like rebasing. For me, it's squash-merge all the way, and I compare the actual diff of the code on my new branch. Diffs are what matter--not commits.
- PUSH_AX 2y agoI haven’t found meaningful use for history in years. Neither has anyone on any of the teams I’ve worked on. Nitpicking git practices really feels like a waste of time. Pick something that works and roll with it.
- RangerScience 2y agoI regularly look up the git blame on lines of code; I’m hoping to get anything from “documentation” on magic numbers, to seeing what else that line went with, although usually to find out who to go ask when I find a WTF. Before I started regularly looking up that ‘blame’, I also didn’t care too much about got history. Now, I put some effort into making my own history useful to everyone (including future me).
- bluSCALE4 2y agoFuture me advocates are the best advocates.
- oopsallmagic 2y agoThen why are you even using a VCS?
- PUSH_AX 2y agoTo work on the same code base as the rest of my team? Like everyone else. Certainly not to nitpick about how history is written, in what order or what is omitted.
- ImPleadThe5th 2y agoI'm very surprised you've never gone hunting for bugs in your git history. "Hey something went wrong with X service" Find commit like "add y to x service' It's a time saver to me. Plus if the bug is extra tricky, you can ~easily~ revert or pick it out.
- 2y ago
- knallfrosch 2y agoIt’s interesting how much devs - including me! - care about git history, yet rarely do we use it in a way that makes the rebase-merge-squash differences meaningful. Usually I just look at the file history, find the work item from the commit message and then understand _why_ the code is the way it is. That is the functionality I need to have in mind when changing the file. Who cares how it came to be?
- oopsallmagic 2y agoPeople need to get comfortable with git being a DAG, and not the degenerate case of just a straight line. Merge commits aren't scary, folks.
- Leszek 2y agoUse `git log --first-parent` and if you merge, write useful merge commit messages. There, I've resolved the difference between merge and rebase forever.
- anordal 2y agoWhy haven't more people heard of git revise? Unless you actually want to transplant your changes onto a new base, honestly, do yourself a favor and use this instead: https://github.com/mystor/git-revise https://github.com/mystor/git-revise Its inability to change your worktree (operates in memory instead) is a big speed and safety feature: It won't invalidate your build, and you can't screw up the end state. It also has features that regular rebase lacks, like splitting a commit and editing all commits at once. I'm more than a big fan of it.
- ivolimmen 2y agoI have been working with git for only 10 years. I know how to fix things when stuff goes wrong. I have no strong opinion on merging strategy. Git is now what my clients are concerned with. I am not getting paid for solving git issues (well not directly, I was never hired for it)
- plasticeagle 2y agoDevelop on a branch. Do whatever you like on that branch, no-one cares. Squash merge to main always. Problem solved.
- swiftcoder 2y agoOne of the biggest barriers to rebasing these days is that GitHub's UX for pull requests doesn't keep track of comments across a rebase-and-force-push. Frustrating for those of us who prefer this style
- oftenwrong 2y agoThe debate about whether to preserve the true history or clean it up is based on the limitations of git log. There is no reason we need to choose. Imagine you could `git summarise` a range of commits. Anyone who wanted a clean, straightforward history could read through the highest level of summarisation. If one wanted to dig deeper, they could peel away the summary and look at the log items below it.
- kovac 2y agoThe man who designed git advises against rebasing as a default merge strategy, but the comment section is filled with comments promoting rebasing and coming up with wildly elaborate schemes to deal with its problems without addressing any of the points raised by Torvalds. Git workflows imposed by those that don't understand git well enough is one of the most annoying things.
- account42 2y agoThe people that develop git also implemented rebase and especially interactive rebase. And added options to make rebase the default for pulls. Perhaps it is you that doesn't understand Linus' points and what they do and do not apply to?
- kovac 2y agoAdding an option to make something default isn't the same as making something the default. If they wanted it as the default, they'd have made it the default. I understand rebase vs merge invokes strong feelings (including in myself), which is exactly why imposing them on others is extremely annoying. Perhaps we just do as we like, but don't presume to know better than everyone else?
- captainbland 2y agoThe only rule about rebasing I care about is the golden rule of rebasing: "Never do it on a public branch". In general I'm not going to waste my team's time by messing about with it otherwise one way or the other, and personally use either rebase or amend depending on context to tidy things up locally, and use merge when interacting with public branches.
- xs83 2y agoI will die on the hill of squash-merge only. It doesnt make the history that confusing having branching visible with some run of the mill standardisation in process. My biggest issue is that if you have to delay a feature then the sheer amount of conflicts you have to resolve (many of which you had nothing to do with) becomes prohibitive. I have no problems with rebasing master or a published branch - thats the release managers problem to deal with everything on but I really dont know where this "rebase everything" comes from
- account42 2y ago> git log @ ^main You can also use `git log main..` to show the commits in HEAD but not in main. I prefer the order of the arguments in the OLD..NEW syntax for the commit range (OLD, NEW] over the reversed order with separate arguments.