[HN Gopher] I kind of like rebasing
___________________________________________________________________
I kind of like rebasing
Author : nalgeon
Score : 146 points
Date : 2024-06-20 19:55 UTC (2 days ago)
(HTM) web link (rednafi.com)
(TXT) w3m dump (rednafi.com)
| quibono wrote:
| Personally 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 wrote:
| 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.
|
| 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 wrote:
| I haven't used Magit or GitUp, but I really appreciate
| JetBrains IDE automatic conflict resolver.
| quibono wrote:
| I'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.
| sjburt wrote:
| The main issue is that on a longer branch, you have to fix all
| the rebase conflicts on the oldest commit. Then, if you changed
| something in the conflict zone, you fix it again on the next
| commit, because the next commit used to be based on something
| else. Sometimes git rerere can help with this, but I find it
| fairly unreliable (could be user error!) If you do a merge, you
| only need to resolve it all once.
|
| Otherwise I tend to prefer rebase.
| Carrok wrote:
| > 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 wrote:
| I 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 wrote:
| Rebase work resulting in atomic commits != squash
| lesuorac wrote:
| Well 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.
| joe_fishfish wrote:
| You can't do stacked PRs without merge commits, not unless you
| really like conflicts anyway.
| seadan83 wrote:
| I 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
|
| 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 wrote:
| > - 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-...
|
| It reduces a ton of manual work ( _scaled_ by how many
| branches you have stacked!) to _one_ operation.
| seadan83 wrote:
| Multiple at once. Good pointer on `--update-refs`!
|
| I can think of quite a few additional concerns. Overall I
| think it comes down to how the team wants to handle code
| reviews.
|
| Personally, I do think if the team is at the level to
| coordinate and execute on a stack list of PRs, there is
| little need to incur extra round-trip times for
| "reviewing" precursor changes and instead focus review
| time where it is explicitly wanted.
|
| Though, I do indeed like stacked PRs over commit-list
| because there is more incremental progress, but it does
| come with some costs. For example, perhaps the last
| reviewer does not like the overall direction that the
| cumulative work has led to.
|
| My experience is that at that rate, it's best to let
| teams decide how they want to operate, formalize somewhat
| how things are shipped, and bias towards shipping. On the
| other end of the spectrum, a person quickly glancing at
| refactoring updates, not having good context on how a
| given PR fits in - it can almost put into question
| whether CR itself is entirely a best practice. Hence, I'm
| a fan of "ship/show/ask". I think it mostly does away
| with the need for stacking PRs with very little downside
| (and upside of greater efficiency, CR is spent time
| reviewing more important code, things that benefit from
| CR and use the reviewers time well, and makes for a
| better flow for the author since they can readily merge).
| edfletcher_t137 wrote:
| Sure you can! In fact you can do magic on stacked branches
| with `rebase --update-refs` that you can't do with merge:
| https://andrewlock.net/working-with-stacked-branches-in-
| git-...
| nailer wrote:
| Interactive 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 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 wrote:
| Is 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 wrote:
| Provided 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.
| skirmish wrote:
| "edit" is useful for splitting a single commit into
| multiple. You couldn't do it with operations you just
| mentioned.
| 000ooo000 wrote:
| > is it possible not to lose the commit description when
| trying to split a commit?
|
| There's 2 cases: 1) extract changes into a commit that
| comes before the original commit, and 2) extract changes
| into a commit that comes after the original commit.
|
| In both, instead of editing the commit you want to split,
| `break` before that commit, and then use `git checkout
| <hash_of_commit_to_edit> <path_to_files_of_interest>` to
| pull the changes of interest out into an new, earlier
| commit. `git checkout -p` is worth a look here.
| Alternatively if the changes are simple enough, you could
| use exec instead of break before the target commit.
|
| For 1) you can commit those extracted changes with a new
| message and then `git rebase --continue`. The original
| commit will then lack the extracted changes, and have the
| original commit message. If you did want to adjust it,
| reword that commit.
|
| e.g. pick c62dfe67 1 pick
| 63dcd748 2 exec git checkout eea68bb8 three.txt &&
| git commit -m "3" reword eea68bb8 3+4
|
| For 2) reference the target commit's message as the new,
| earlier commit's message. Keep in mind that the git
| invocation in this exec here still supports git aliases so
| if this was something you do often, you could create an
| alias for retrieving the next commit message and that last
| part of the exec could just be `.. && git
| getnextcommitmessage`
|
| e.g. pick c62dfe67 1 pick
| 63dcd748 2 exec git checkout eea68bb8 four.txt &&
| git commit -m "$(git log -1 eea68bb8 --format="%B")"
| reword eea68bb8 3+4
| baq wrote:
| My only gripe is after 15 or so years with git I still
| sometimes forget the direction of the time arrow in the
| interactive rebase.
| formerly_proven wrote:
| I like that and use it a lot. It's very easy to rearrange
| stuff.
| switchbak wrote:
| I 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 wrote:
| Not 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.
| latentsea wrote:
| As someone in the "merge-only" camp, for me it simply boils
| down to I don't think rebasing solves anything I view as a
| problem and as such I just don't care to know anything about
| it. You can rebase if you want, but don't bother trying to talk
| to me about it.
| Nullabillity wrote:
| You _can_ rebase, but you 're still:
|
| - Creating a false history that will be harder for you to
| understand in the future
|
| - Creating a history that tools will have a harder time dealing
| with in the future
|
| - Doing so for no actual benefit (in 99% of cases)
| IshKebab wrote:
| Rebasing 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 wrote:
| Git rerere basically solves this: https://git-
| scm.com/book/en/v2/Git-Tools-Rerere
| recursive wrote:
| > 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 wrote:
| > 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.
| IshKebab wrote:
| Yeah that's fine, you can just push the series of commits and
| then squash them when they are merged. Both Gitlab and Github
| can do squash merges.
| joshuanapoli wrote:
| I 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 wrote:
| In 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 wrote:
| You 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 wrote:
| But 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 wrote:
| Highly 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 wrote:
| >- 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.)
| fouc wrote:
| You're assuming it is not an old bug and that the branch is
| somehow kept around for other developers to re-open months
| or years later.
|
| A PR for each commit seems overkill. Usually a PR is for a
| feature, but code-wise, a feature might require several
| atomic changes. For example: prepare configuration, move
| files around, add tests, add new code, delete old code,
| refactor. Each of those could be a separate commit,
| bringing you to a polished feature with test coverage.
| jaredsohn wrote:
| Might depend on how companies use git but I just verified
| I can see commits for PRs from 2017 in my work codebase;
| could bisect that if needed (although code likely is no
| longer relevant.)
|
| I think splitting PRs into multiple commits can make
| sense when there are only 2-3 commits but you're right
| that it doesn't when there are more than that.
| pizza234 wrote:
| > 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.)
|
| Absolutely. Indeed, this (independent commit) is a very
| positive side effect (typical example: separating
| refactoring commits).
| mrinterweb wrote:
| Another benefit of not squashing is it encourages devs to
| think about their commits and is a great opportunity to
| document what you are doing when they are doing it. If you
| are squashing 10 commits with junk commit messages (because
| devs know there is little value in having meaningful commits
| in what will be a squashed branch), trying to summarize all
| the changes into a meaningful commit message is hard. It can
| be valuable to see the intention of atomic commits in git
| history. The squash branch on merge strategy is just lazy and
| is counterproductive to having meaningful git history.
| jaredsohn wrote:
| I prefer to add commentary in the PR on the final changes -
| what does it do, how does it work, what are some pieces of
| code I'm less sure of, etc. It is accessible since the
| squashed commit gets linked to it and that provides a place
| for people to ask questions.
|
| Also is a lot faster to write and easier to communicate
| compared to messing around with moving code across commits,
| ensuring tests pass across them, etc.
|
| Basically I think people care more about what was built and
| how it works rather than how to split it up step by step
| (although if the latter is important I can add a comment
| for that on the PR - although ideally it would have been
| separate PRs.)
| 000ooo000 wrote:
| >I prefer to add commentary in the PR on the final
| changes
|
| That vanishes when you shift forges
| sjburt wrote:
| I think the problem is that often the order you want it in
| a clean history is not exactly the chronological order it
| was developed. Eg you may build out a feature vertically,
| tweaking the interfaces between the components as you go
| along. But a clean, atomic git history would probably
| introduce each component in a finished state in separate
| commits.
| recursive wrote:
| This depends on the assumption that going to the trouble of
| making a carefully curated commit history well documented
| is even worth the trouble. Sometimes it might be, but I
| don't think it's a given.
|
| > The squash branch on merge strategy is just lazy
|
| "Lazy" is the negative way of saying "easy" or even "more
| efficient". "Lazy" implies that the other way is better. Is
| it? Maybe sometimes.
|
| Am I "lazy" if I walk on my feet instead of my hands? It
| really is a lot easier.
| erik_seaberg wrote:
| git log --first-parent shows the merges but not the complete
| history of each merged branch. git log --first-parent --patch
| displays all the changes that came with a merge as if it were
| one big squash commit (in general git log --patch diffs trees,
| not single commits).
| fleekonpoint wrote:
| I 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.
| elijahbenizzy wrote:
| 100% 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 wrote:
| _> git is entirely immutable data store_
|
| Not entirely, since git can automatically garbage collect
| commits that aren't reachable.
| edfletcher_t137 wrote:
| > 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 wrote:
| Step 3 can be simplified slightly be doing git fetch && git
| rebase origin/main. No need to check out the local main.
| blcArmadillo wrote:
| Or: git pull --rebase origin main
| rednafi wrote:
| TIL. Thank you.
| xyzzy4747 wrote:
| If you're using complicated git commands, you're probably doing
| the wrong thing.
| quibono wrote:
| I guess it depends on what you mean by a complicated command.
| kkfx wrote:
| Rebasing 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 wrote:
| Ah! 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 wrote:
| I'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
|
| (I'm putting "private" and "public" in quotes because they're
| really on a spectrum)
| ruraljuror wrote:
| I 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 wrote:
| In 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.
| singpolyma3 wrote:
| Especially when it's an open PR. That's effectively
| essential in order to, say, address feedback
| quectophoton wrote:
| > 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.
|
| That's kind of the point though: being reasonably sure that a
| commit contains a tree that the committer _had seen_ at some
| point, instead of making up history with commits that contain
| trees that the committer never saw at any point at all.
|
| When someone rebases `n` commits, experience has taught me I
| can't trust any commits other than `HEAD`; chances are any
| commit printed by `git log "HEAD~${n}..HEAD^"` was never
| checked out by anyone, much less tested at all.
|
| CI pipelines also usually run only against HEAD at the moment
| of push, so if someone pushes `n` commits, then `n-1` are
| usually ignored by CI pipeline.
|
| Modifying options for compiler or linter or formatter checker;
| adding a new dependency or updating an existing dependency's
| version; changing default options for the project. Stuff like
| that might make those commits useless, and if someone notices a
| problem in HEAD after rebase, and decides to fix it, even if
| the fix is moved to the earliest possible point, nobody would
| bother re-testing all those n-1 commits after the fix was
| added, leaving broken commits useless for git bisect.
|
| So I agree that rebase is nice. How most people use it, though,
| not so nice.
| rednafi wrote:
| This assumes the rebasing will be done in a shared branch.
| Two rules of rebasing:
|
| 1. Never rebase a shared branch 2. Never break rule 1
| lmz wrote:
| No, that describes rebasing and preserving the intermediate
| commits. Of course, if you squash into one commit at merge
| time, this won't happen.
| osigurdson wrote:
| I think most people these days just look at PRs. Everything
| else is largely noise.
| saagarjha wrote:
| Not at all. Someone's got to look at your commits in the
| future when your code breaks ;)
| kazinator wrote:
| Quite often, that someone is you.
| Buttons840 wrote:
| In a merge-based workflow you can have commits like "wip" or
| "before lunch"; no reason to believe those were ever tested
| either.
|
| I like rebasing but it's ultimately up to the author. Even
| tools like Fossil, that don't have official history rewriting
| tools, don't ensure that history has never been rewritten
| because people can use external tools to do the rewriting
| (and I've done this).
| martin-t wrote:
| Use a temporary branch for those. When you come back, undo
| the commit (git test -- hard if memory serves but i just
| have an "uncommit" alias) and commit the fully finished
| work to the real branch.
| Buttons840 wrote:
| This _is_ destroying the "real history" though. (Which
| again, I'm fine with, I like rebasing.)
|
| Two months from now I'm quite likely to say something
| like "oh yeah, I remember I encountered a bug related to
| that, I was trying to fix it before lunch". The "wip" and
| "before lunch" commits are just as likely to be relevant
| in the future as any other.
|
| It's nice to assume that all commits will compile and
| pass the tests, but it's sometimes useful to have a
| snapshot of that weird compiler error you encountered. So
| much for our nice assumption.
|
| This is why I say it's all up to the author, and if the
| author likes rebasing, I don't think anyone should have a
| problem with that. (Don't rewrite public branches, of
| course.)
| martin-t wrote:
| There's levels of granularity that matter. You could just
| as well record all your edits in realtime. Make a script
| that makes a commit every second or every time you finish
| editing a line. It might be interesting later, yet that's
| usually not how people use git. Those changes wouldn't be
| meaningful units of work.
|
| If you make a commit "wip" or "before lunch" because you
| want a backup of your work or want to continue on a
| different computer, then it's not a meaningful unit
| either. It's OK to throw away.
|
| Most people prefer less granular commits but not to the
| point of having 1 commit per issue/PR. For example after
| inheriting someone else's code written in a hurry and not
| tested, I often end up dividing my work into several
| commits - first there's a cleanup of all the things that
| need renaming for consistency, adding docs/tests,
| removing redundant/unused code, etc. sometimes this ends
| up being more commits as i reveal more tech debt. Then,
| when i am confident i actually understand code and it's
| up to my standards, I make the actual change. This can be
| again multiple commits. The first and second group are
| often mixed.
|
| And it's important when it later turns out i broke
| something - i can focus on the commits that make
| functional changes as the issue is usually there and not
| in the cleanup commits which can be 10x larger.
|
| BTW what git is really missing is a way to mark multiple
| commits as one unit of work so the granularity stays
| there but is hidden by default and can be expanded.
| rawling wrote:
| > BTW what git is really missing is a way to mark
| multiple commits as one unit of work so the granularity
| stays there but is hidden by default and can be expanded.
|
| Is that not just a non-FF'd, non-squashed merge of a
| branch?
| martin-t wrote:
| That's the closest you get today but it means having to
| make, merge and delete branches all the time. What i
| propose is something like git squash but that keeps the
| history internally. It would present as one commit in
| gitk and other GUIs but could be expanded to see more
| detail.
| saghm wrote:
| > That's kind of the point though: being reasonably sure that
| a commit contains a tree that the committer had seen at some
| point, instead of making up history with commits that contain
| trees that the committer never saw at any point at all.
|
| I don't really understand why this would be important. If I'm
| the one committing, I can rebase however I want to rewrite
| history before merging, so if I'm super adamant that a commit
| that looks a certain way exists, I can just make that commit
| and then put commits around it as needed to ensure that it
| can be merged with by fast-forward to preserve it. If I'm not
| the one committing, why should I care about what intermediate
| states that the person who committed them don't even care
| about enough to preserve?
|
| To me, the issue seems more that the UX for doing this sort
| of thing is not intuitive to most people, so the amount of
| effort needed to get the history rebased to what I described
| above often ends up being higher than people are willing to
| spend. This isn't a particulary compelling argument to me in
| favor of merging workflows though because it doesn't end up
| making the history better; it just removes most of the
| friction of merging by giving up any semblance of sane commit
| history.
|
| (edited to add the below)
|
| > When someone rebases `n` commits, experience has taught me
| I can't trust any commits other than `HEAD`; chances are any
| commit printed by `git log "HEAD~${n}..HEAD^"` was never
| checked out by anyone, much less tested at all.
|
| I definitely agree that generating broken commits during a
| rebase is not a good thing for anyone, and I'd be super
| frustrated if I had teammates doing that. At least
| personally, I make sure to compile and run unit tests before
| continuing after each step of a rebase after I've fixed
| conflicts; there's even the `x` option in an interactive
| rebase to execute a command on each commit (which will halt
| and drop into commit and allow you to amend before continuing
| if it fails), which is unfortunately not super well known.
| kazinator wrote:
| If you want the full history of someone's work, you need all
| the edits. Including all the times they backspaced over the
| typo. With down-to-the-millisecond timestamps attached!
| cryptonector wrote:
| When I rebase I diff after each rebase to check that the only
| diffs are the ones I intended. So I, the committer, have seen
| all my rebased commits.
| rictic wrote:
| Sure it looks nice, but it's a fake history. After a rebase you
| have commits where no one's ever run the tests, no author ever
| intended to get the repo into that state. Hell, most likely no
| one knows if the code even compiles.
|
| It's assuming that that merge conflicts will never be too
| difficult, and people won't make mistakes in resolving them. If
| so, too bad, the original commits are lost by the rebase
| process. (They might or might not be kept in any given clone.
| No guarantees, good luck trawling through the reflog.)
|
| It's corrupting your database because it makes the UI for
| exploring it nicer.
|
| This is the opposite of what we should be doing! If the truth
| is messy we should build better UIs for exploring it. Add
| additional information on top of the true history, allow people
| to group and describe commits. Add more information to get the
| UI that you want, rather than destroying information because it
| makes things look cluttered.
| AceJohnny2 wrote:
| > _After a rebase you have commits where no one 's ever run
| the tests, no author ever intended to get the repo into that
| state. Hell, most likely no one knows if the code even
| compiles._
|
| That is the role of the CI system.
| lmz wrote:
| CI will usually only run the latest commit. Even if commit
| a, b, and c were all tested, the resulting commits a', b',
| and c' after rebase would usually only have the last one
| tested.
| skybrian wrote:
| Since you shouldn't publish commits that weren't tested,
| this suggests you should publish only one commit at a
| time.
|
| (Unless you think "works on my machine" is good enough
| testing. Sometimes it is.)
| 000ooo000 wrote:
| >After a rebase you have commits where no one's ever run the
| tests, no author ever intended to get the repo into that
| state. Hell, most likely no one knows if the code even
| compiles.
|
| Only true if the commit author doesn't do so, and it is
| trivial to do so, either during or after a rebase using the
| rebase exec command. So given this is a discipline issue no
| different from a developer authoring a change without testing
| it, I fail to see how this is "rebase"'s fault.
|
| >it makes the UI for exploring it nicer
|
| Not to imply I accept the "corrupt database" opinion, but I
| think it's worth saying that aside from the collaborative
| element of VCS, commits exist for the purpose of exploring
| past code changes. A practice which improves that seems sound
| to me.
|
| >we should build better UIs for exploring it
|
| Go right ahead :)
| Nullabillity wrote:
| > Only true if the commit author doesn't do so, and it is
| trivial to do so, either during or after a rebase using the
| rebase exec command. So given this is a discipline issue no
| different from a developer authoring a change without
| testing it, I fail to see how this is "rebase"'s fault.
|
| "Undisciplined enough to use rebase, disciplined enough to
| put in extra effort to mitigate _some_ of the harms of
| rebase " is an imaginary intersection.
|
| > Go right ahead :) git log --first-
| parent
| singpolyma3 wrote:
| Nothing prevents people from committing untested code that
| doesn't even compile without any rebase involved. Even hooks
| don't help since the incompetent coworkers are just barely
| smart enough to learn about -n
| danlugo92 wrote:
| Honestly I dont even do history anymore for small projects, I
| bisect twice a year tops and I have never evee have had to look
| at a 3 year old commit to figure out a bug, not that the code
| could'nt be 3 years old but the blame is so tangled at that
| point..
| stavros wrote:
| I've been a developer for twenty four years. I've seen a lot of
| people have strong opinions about whether to merge or rebase,
| to squash or not to squash. I haven't seen one single time
| where it made a difference whether something was merged or
| squashed, as I've never seen anyone look at commit messages in
| depth, versus tickets or PRs or bisecting.
| dnadler wrote:
| Really?
|
| I certainly have used commit messages and seen others do the
| same. Perhaps this is more an indictment of the quality of
| the commit messages than anything else.
|
| In my experience, rebase and squash makes it easier to
| collect work into meaningful groups and thus write more
| helpful/informative commit messages.
|
| I can think of a few times off the top of my head when I
| referred back to a detailed commit message in a repo to
| understand why a change was made.
| stavros wrote:
| If I'm making a change that people are likely to wonder
| about, I tend to add comments. Basically, anything that's
| not obvious tends to get a comment, change or no.
| citrin_ru wrote:
| I read 'git log -p' often, and linear history makes it so
| much easier. The same with bisecting. I'm yet to see any
| practical advantage of not allowing rebase/squash in feature
| branches. Preserving _all_ history of feature branches is not
| an advantage to me. The history I care about is the history
| of the main branch and I don 't want to see it splint into
| many tiny commits, especially not into commits looking like
| add/fix/fix/fix/fix where at all point except the last the
| code is broken.
| klysm wrote:
| The problem I run into is when a developer merges the main
| line branch into their feature branch repeatedly to get new
| changes. Now your branch is completely tangled up and
| difficult to change
| recursive wrote:
| I do this like... all the time. At least weekly for the
| last 5 years maybe? I can't remember a time where this has
| caused anything to get tangled or difficult.
| klysm wrote:
| Cherry-picking is harder. Splitting up the branch is
| harder.
| recursive wrote:
| I cherry pick occasionally. I don't see how it's affected
| at all? Edit: If another dev and I both cherry pick the
| same commit concurrently, that might do something weird.
| Maybe that's it?
|
| I don't know what splitting up a branch means.
| richbell wrote:
| https://lore.kernel.org/lkml/CAHk-=wjbtip559HcMG9VQLGPmku
| rh5...
| recursive wrote:
| Merges I create from the CLI don't really look that
| differennt from the ones through some forge UI PR
| process. I don't know what Linus is getting at. If I was
| working under someone who had a process like this, I
| could ask them to clarify what they wanted me to do. I
| don't have that. And I need to be able to justify all of
| my decisions. So this isn't useful to me.
|
| I don't doubt that Linus has good reasons for all this. I
| just don't know what they are. And I don't know if
| they're applicable to other repos.
| singpolyma3 wrote:
| ...why? Isn't this exactly what rebase is for? Just
| plain, boring, non-interactive rebase.
| david_allison wrote:
| For what it's worth, I often look at commits/commit messages
| in-depth.
|
| I wouldn't do so if the history were a mess
| rurban wrote:
| Exactly. The only true history is the clean, properly rebased
| history with one change per commit, as I want it.
| lr4444lr wrote:
| Preach, brutha!
| eschneider wrote:
| I generally prefer a rebase-free workflow (mostly due to my
| upbringing. Long story...) But other than rebasing shared
| branches, which (with notable exceptions) is a Wrong Thing,
| it's mostly up to teams to decide on a workflow that gets
| things done for them. As long as there's a consensus on how to
| do things, go with god.
| Nullabillity wrote:
| > 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.
|
| Was the bug introduced by the rebase, or was that code always
| broken?
| singpolyma3 wrote:
| Code doesn't exist until it is merged, so these are
| equivalent
| mrinterweb wrote:
| 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".
|
| 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 wrote:
| > 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.
| mrinterweb wrote:
| > 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.
| tkiolp4 wrote:
| I deleted that part because it sounded the wrong way (it
| wasn't my intention to question your experience, but a
| genuine curiosity)
| mrinterweb wrote:
| Git has great tools. It sounds like you'd want to see
| everything associated with a merge commit. If what you're
| looking for is a certain way to view changes, git's built in
| tooling usually has you covered regardless of commit
| strategy.
|
| So if you know a commit sha and you'd like to see all of the
| merged branch changes associated with that commit as a single
| patch, I cooked up a script that takes a commit sha and finds
| the merge commit and show all the changes in a consolidated
| patch.
|
| #!/bin/sh
|
| merge_commit=$(git log -n1 --merges --pretty=format:"%H"
| $(git rev-list --ancestry-path $1..HEAD --merges -n1))
|
| git show -m -p --stat --format="" $merge_commit
| parpfish wrote:
| What do you do with the commits that are "incomplete"?
|
| I frequently get halfway through building something, but the. A
| more urgent project comes up and i need to commit my half-done
| non-functional work so I can hop onto a different branch
| erik_seaberg wrote:
| I stash half-baked work to keep it separate from quality
| commits. When I come back to the stash, I may or may not like
| where it was going and decide to build on it.
| parpfish wrote:
| Stashing always makes me nervous.
|
| For some reason it feels ephemeral and I worry that I'll
| lose the stashed changes like when you accidentally
| overwrote the copy/paste clipboard
| recursive wrote:
| Yes, I generally don't use it much, because it forces me
| to remember that I have stashed work.
| deredede wrote:
| I used to feel this way because I lost work to `git stash
| pop` in the past, but there is now a nice feature where
| if you `git stash pop` and it doesn't cleanly applies,
| git keeps the stash and I use it more often now.
|
| That said for me the stash is usually used either for
| temporary stuff (eg taking my current work to another
| branch) or for things that might be useful to reference
| later but I will rewrite differently anyways; stuff I
| want to keep goes into a WIP commit.
| klyrs wrote:
| Committing everything to a new (temporary) branch, and
| returning to your current branch, costs nothing and saves
| the headache of stash's weirdness.
| mrinterweb wrote:
| I create "WIP" commits, and then I squash those. I squash
| intentionally to clean up commits that should be together.
| kutenai wrote:
| I take all "WIP" branches and rebase them as needed onto the
| 'latest' development. Any continued work on those branches
| will have to be compatible with all released code, so deal
| with any issues -- i.e. merge issues during a rebase -- now,
| rather than later when you try and submit a PR.
|
| As a team leader, I prefer to avoid "a lot of" WIP branches,
| but I just expect developers to rebase their WIP onto dev,
| etc.
|
| Oh, and I really really dislike "merging" develop into the
| WIP branch. This accomplishes the same thing as "rebasing"
| the WIP branch onto develop, but it leaves a horrible mess
| behind.
|
| Frankly, I don' give a hoot about some "history" of work. In
| the end, I care about the unit of work encapsulated in that
| WIP branch, and that unit must always add on top of develop.
| Rebase just makes that super clear.
| kcrwfrd_ wrote:
| I usually use stash for this stuff. But alternatively you can
| commit and then come back and squash / rebase to clean up the
| commit history.
| tmtvl wrote:
| Atomic commits are also really nice for when some stealthy
| tricky bug appears and you need to git bisect to find out where
| it was introduced. Ending up with 'the bug got introduced
| somewhere in this massive commit that touches nearly every part
| of the system' is not very helpful.
| zikohh wrote:
| I agree 100%. I also like using FF only. Reviewing commits is
| part of the code review process - their to title, description
| and code. If the commits are not atomic and clear I don't
| approve the merge request (MR); I believe the MR is a full
| snapshot of what will go to main.
|
| It's so frustrating to see 7 commits for one MR and it's a 10
| line change.
| GauntletWizard wrote:
| Branches should be small enough and short lived enough that
| they are atomic commits. Merge early, merge often, don't break
| things. Work on small pieces that don't change functionality,
| The missing part of this is that this causes you to need merge-
| trains earlier - You'll want to start "stacked" commits that
| are based on the pieces that are atomic but not merged. That
| sucks, because the tooling isn't yet great at handling that -
| It should be possible to mark and auto-rebase all your local
| branches in that dependency chain,
| deredede wrote:
| I generally prefer PRs that have multiple atomic commits to be
| split up in separate PRs. If the atomic commits can't be
| reviewed separately/introduce non-working states, they are
| probably too small.
|
| > One rule I have for any rebasing is, when there may be more
| than one person using the branch, no more rebasing that branch.
|
| That is the one rule to obey for rebasing to be useable at all.
| jaza wrote:
| I 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 wrote:
| This may be rose-tinted glasses, but I was fine with merges with
| Mercurial / 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 wrote:
| The 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 wrote:
| I 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 wrote:
| Never rebase shared branches.
| kutenai wrote:
| I'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 wrote:
| GitHub 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 wrote:
| Everyone'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.
| phendrenad2 wrote:
| Great, just don't force it on me, or grumble when not everyone on
| the team does it.
| dham wrote:
| I 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 wrote:
| I 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.
| osigurdson wrote:
| The 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 wrote:
| Always use --force-with-lease.
| rednafi wrote:
| This 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 wrote:
| Two rules of rebasing that I follow strictly:
|
| 1. Never rebase a shared branch 2. Never break rule 1
| rurban wrote:
| Always rebase and push --force. Devs who cannot pull --rebase
| or reset --hard to latest should quit their jobs, and stop
| whining.
| osigurdson wrote:
| True Scotsman. Does it or does it not increase cognitive
| load?
| osigurdson wrote:
| What is your definition of a shared branch? Is it shared the
| moment you push it (assuming a github like workflow). Is it
| shared if you check it out on two separate machines just for
| yourself?
| rednafi wrote:
| My definition of a shared branch is the one where only one
| person is working. It can be your local branch and the same
| one after you push it to remote. It's still not shared in
| the sense that only 1 person is supposed to work on that
| branch.
|
| In this case, you can easily perform rebase and run `git
| push origin HEAD --force-with-lease` without causing any
| headache for anyone else.
| peter_l_downs wrote:
| Enforce 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 wrote:
| Yep. Neither the rebase nor merge workflow negates the benefits
| of squash-merging to main.
| breatheoften wrote:
| Strongly 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.
| Taylor_OD wrote:
| I 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 wrote:
| This 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 wrote:
| Not 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 wrote:
| And 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 wrote:
| True, good point. Makes sense! Thanks for the improvement!
___________________________________________________________________
(page generated 2024-06-22 23:01 UTC)