11 ms·
Take Advantage of Git Rebase
- placatedmayhem 4y agoRebase has become so integral to my workflow, it's hard to imagine living without it. I intentionally avoid merge commits, including configuring git pull to rebase rather than merge. I find it so much easier to commit a bunch of tiny iterations while doing local testing, rebase and squash them, then post them for review. As a bonus, I frequently push after each of those small commits to a feature branch so I don't have to worry about losing work if my drive dies.
- robertlagrant 4y agoThis might be obvious, but it's worth checking out git commit --amend. Then you can be regularly committing, but to the same commit.
- shagie 4y ago--amend would interact with the remote system poorly if there's a push with each commit.
- sjburt 4y agoYou have to force push, but you have to do that when pushing a rebased branch as well. In either case it’s a history rewrite. It’s not a big deal unless other people have pulled that branch—if they have they will need to reconcile things on their end as well.
- dnsmichi 4y agoDepending on the workflow and collaboration in branches in teams, amending may not be ideal. Amending changes to an existing commit will generate a new sha checksum, thus resulting in a diverging history if the branch is often pushed to the remote Git server. That's one of the rare cases where "git push --force" makes sense but also requires awareness for other collaborators on the branch - they need to run "git fetch && git reset --hard origin/branchname" every time, and best "git stash" to temporarily remove any local changes, with running "git stash pop" afterwards. One reason to regularly push commits can be to trigger CI/CD, security scanning and dev/staging deployments or review apps. GitLab team member here - before joining GitLab in 2020, I was a Git/GitLab trainer. https://www.netways.de/en/blog/2018/05/24/releasing-our-git-and-gitlab-training-as-open-source/ https://www.netways.de/en/blog/2018/05/24/releasing-our-git-...
- tspike 4y agoI've completely replaced my use of --force with --force-with-lease. It does the same thing, except it will abort if the upstream branch has been updated since your last pull. This pretty much prevents the concerns about clobbering others' work.
- dnsmichi 4y agoAfter reading this comment about "git push --force-with-lease" in https://stackoverflow.com/a/53011907/1821348 https://stackoverflow.com/a/53011907/1821348 my workflows with "git fetch" first would not work with "git push --force-with-lease", behaving as if "git push --force" was run. Theoretically - I need to do some testing here. Thanks for the pointer into learning something new :)
- robertlagrant 4y agoFor sure, it doesn't work with every workflow. But I think it would for the OP's described workflow. And I am currently waiting for my GitLab backpack for contributing something (very small, but apparently it counted!) so thank you to the team for that!
- dnsmichi 4y agoThanks for sharing your ideas, appreciate the thoughts to learn new perspectives :-) And also thanks for contributing, every contribution counts and helps :-) Maybe see you at a future hackathon :) https://about.gitlab.com/community/contribute/ https://about.gitlab.com/community/contribute/
- usr1106 4y ago--amend if you have a modification to your most recent commit. --fixup if you have a modification to an earlier commits rebase --autosquash amend the fixup(s) to the commit(s) they belong too. (Of course you need to know what you doing. Otherwise you create conficts tedious to resolve in the rebase)
- agumonkey 4y agothen there's autosquash and similar honestly the commit graph as a first-class value yields a lot of ideas in my mind, we should be investigating compute at the subtree layer more often.
- rrwo 4y ago> Rebase has become so integral to my workflow, it's hard to imagine living without it. Same. I use it to reorganise branches before submitting change requests or merging: - Combing or splitting commits so that each commit contains a small unit of a logical change - Reordering commits to related changes are near each other - Reordering commits so changes that are depended on by later commits occur earlier. - Rewording commit descriptions to have a lengthy explanation, if needed - Removing small commits that fix minor typos It's a great way to turn the commit history of a project into one of logical changes, rather than a simple temporal log of every change. (I had a colleague who was so used to CVS and couldn't get his head around not using version control as a time tracking device.)
- thunky 4y ago> It's a great way to turn the commit history of a project into one of logical changes, rather than a simple temporal log of every change. This seems a bit like an unhealthy obsession. I would be curious to know if the benefits of having a perfect git history outweigh the costs. A temporal log of changes is good enough for me.
- placatedmayhem 4y agoSpecifically, more atomic commits make rollbacks easier when issues with a change are discovered after merge (e.g., in integration and user acceptance testing). In the very active code bases I've worked on, generating a rollback commit for a single commit is far more straightforward than having to deal with a merge commit that potentially includes other merges (e.g., with `git pull`'s default behavior). In fact, GitHub's pull request UI has it as a single button.
- thunky 4y agoWouldn't these types of changes more commonly be caught while testing against a branch? Also in many cases I would think that the fix ends up being even smaller (or bigger) than a single commit (the commit isn't actually atomic). Maybe the codebases I've worked on weren't active enough for this to be a common problem. But also, having too many cooks in the kitchen may be a part of the problem here too.
- rubyist5eva 4y agoPersonally, I actually stopped using rebase or advocating it's use (because noobies mess up their history all the time with it). I just commit whatever, then when the code is merged to trunk/dev/master/whatever I use `merge --squash`. Reviews are very rarely happening on the commit level, so having lots of small "meaningless" commits (lint fixes, fix spec, add thing) hasn't been an issue but having squashed merge commits (effectively a rebase that squashes everything) has made release management so much easier for our team. It also has the benefit of just less cognitive overhead of micro-managing my feature branch commits that are WIP or currently in-review.
- jokab 4y agoThanks. I thought it was just me.
- dabears 4y agoThis is my workflow as well, it's great. Github is configured so merging a PR into master will automatically produce a squashed commit. My rule of thumb, always rebase unless you hit a series of merge conflict while rebasing. Then either merge, or squash your branch then re-run the rebase.
- rubyist5eva 4y agoWe require linear history on our shared mainline branches so the squash workflow works great for us using Github as well. Another benefit is the "show changes since last review" option when reviewing a PR - it's been a while but I'm not sure if this is possible with a rebase-based workflow.
- gregmac 4y ago> Rebase has become so integral to my workflow, it's hard to imagine living without it I'm the same. I commit frequently. A lot of those end up being `--amend`, but a lot of time I will rebase and squash/reorder/etc. In fact I'd say the majority of time I push changes I've rewritten my local history at least once. According to any git history you'd find from me on the server, you'd think I never accidentally commit syntax errors, break unit tests, and that when I do big structure changes or refactors I get it the way I want it on my first attempt. > including configuring git pull to rebase rather than merge It annoys me a bit this isn't the default -- at least for teams that work from a single centralized git repo (eg: almost all corporate dev, and the majority of open source). I've done it for years and have never had any issue with it. It doesn't rewrite anything but your local (non-pushed) history, which is totally fine. (Unless you are working with multiple remotes, in which case it causes chaos, which I think is why it isn't the default). Are there other drawbacks?
- DrBenCarson 4y agoEasily the most underutilized and poorly understood part of the typical git workflow
- boleary-gl 4y agoI don't know if Christian would go this far, but I actually put this into my ~/.gitconfig so that I'm always rebasing [pull] rebase = true edited for line spacing
- greatpostman 4y agoWow did not know this existed. I’ll add it to my config
- augusto-moura 4y agoJust a nit on the HN comment, you can indent the lines 2 spaces so that it shows up as a code block, it should maintain the correct spacing/line wrapping and it uses a monospaced font as well like this
- boleary-gl 4y agoThanks - today I learned
- dnsmichi 4y agoToday I learned, thanks a lot! Created a MR for the Developer Evangelism Hacker News handbook to add this formatting tip, and some more https://gitlab.com/gitlab-com/www-gitlab-com/-/merge_requests/112729 https://gitlab.com/gitlab-com/www-gitlab-com/-/merge_request...
- dnsmichi 4y agoYou are more brave than I am - I have it explicitly disabled :-) https://gitlab.com/dnsmichi/dotfiles/-/blob/main/.gitconfig https://gitlab.com/dnsmichi/dotfiles/-/blob/main/.gitconfig When I pull and it runs into a merge conflict, I want to see that error/log on the CLI. Reason: Sometimes the automated pull-rebase takes a very long time to resolve conflicts after each step. I prefer to first run git fetch git diff branchname origin/branchname and then decide my strategy :) Bit off-topic but since we share .gitconfig tips - I upgraded to a recent Git version and enabled the "git push" option to setup tracking automatically. No more "git push -u origin branchname" actions. https://gitlab.com/dnsmichi/dotfiles/-/blob/main/.gitconfig#L19 https://gitlab.com/dnsmichi/dotfiles/-/blob/main/.gitconfig#... [push] autoSetupRemote = true
- OJFord 4y agoI don't know if it's possible to write an article like this and not just be preaching to the choir; ignored by the flock that's already decided it doesn't like it.
- chris_wot 4y agoSo what? If the crowd doesn't want to use it, what of it? You only rebase on your own changes before you push the patches.
- OJFord 4y agoWell my suggestion really was just that it's pointless to write about, because you won't convert anyone. (Not '..and you should be doing xyz because that will convert them and that's what we want'.) But to answer your actual question, there are various ways in which what others on a team do affects you: - CI building 'merge branch master' all the time on master, because of merge-pulling upstream changes after committing - spaghetti merge feature branches (that you might be reviewing, working jointly on, or as below) - git log, blame, etc.
- chris_wot 4y agoYeah, rebasing in master is a huge no-no. LWN has a great article: https://lwn.net/Articles/328436/ https://lwn.net/Articles/328436/ Linus Torvalds explained it best: https://lwn.net/Articles/328438/ https://lwn.net/Articles/328438/
- OJFord 4y agoIf you have local, un-pushed commits 'on' master, and there are upstream changes to master that you lack locally, there is absolutely nothing wrong with pull.rebase, i.e. rebasing your local changes on the upstream ones before you push. Beats the hell out of: * deadbeef (master) Merge branch 'master' of upstream |\ | * feedbeef A proper commit message from upstream * | deafbeef A proper commit message of the actual change |/ which not only hides the real commit message in CI, but also flips around the history so master's snaking around between upstream's path and the person not pull.rebase-ing's path.
- holoduke 4y agoRebasing is merging multiple commits to one commit right? Basically you commit your small changes to your local master branch and at some point you merge them to one commit and push them to master repo?
- hkdobrev 4y agoThat's squashing which could be achieved with rebasing, but rebasing is larger than that which allows you to order and edit your history.
- dnsmichi 4y agoGitLab team member here. You can use `git rebase` to perform the so-called "squash" action, that squashes multiple commits at once. For example, the latest commits in the branch look like this: 123 WIP1 456 WIP2 789 WIP3 012 FeatureA WIP1,2,3 as commits should be merged into a single Git commit, and be put on top of the FeatureA commit - so to speak, use the FeatureA commit as a new base. Git uses the rebase command to do exactly that - you'll perform an interactive rebase onto FeatureA commit. The interactive rebase allows you to define specific actions. "pick" keeps the commit. In order to perform a squash of the WIP1,2,3 commits, you'll keep the first WIP1 commit, and tell Git to continuously squash the next commits WIP2 and WIP3. Each operation is done at once. pick 123 WIP1 squash 456 WIP2 squash 789 WIP3 pick 012 FeatureA This results in a new history and commit - squashing changes the commit sha checksum, with new content in the Git commit, as well as a new base commit. 567 Squashed 012 FeatureA "squash" in an interactive rebase keeps the individual commit messages for each commit, and at the end, the editor for commits allows you to edit the final messages. This can be helpful to review the squash action, and for example amend or abort it. If you plan to not keep the individual commit messages, "fixup" throws them away and can be used as alternative action. "git rebase -i" has more options - you can also stop at a specific commit, and amend it, e.g. when a "git add" was missing a file earlier. Note: Any change to a commit within the Git history forces all later commits to change too, as the linked commit base changes too, thus regenerating the sha checksum. This entirely rewrites Git history trees, and can be very invasive - if you intend to keep specific commit IDs (for release tags for example), ensure that the workflows to not allow rebasing on certain branches. One possible workflow is to keep the main default branch protected, disallowing to rebase and push a changed history, add git tags there, and only rebase in a Merge Requests branch prior to review/approve/merge cycles. Moving from Git commands to GitLab - GitLab also offers a Merge Request option to squash commits automatically when the MR is accepted, so that all commits in the MR branch are squashed, and you don't need to do it manually. https://docs.gitlab.com/ee/user/project/merge_requests/squash_and_merge.html#set-default-squash-options-for-a-merge-request https://docs.gitlab.com/ee/user/project/merge_requests/squas... Last but not least - the quick action /rebase in a MR comment allows to trigger a rebase via the UI too, thus not requiring client side clone/fetch/rebase. More tips in https://about.gitlab.com/blog/2021/02/18/improve-your-gitlab-productivity-with-these-10-tips/ https://about.gitlab.com/blog/2021/02/18/improve-your-gitlab...
- secondcoming 4y agoBeen using git for 10 years now, never rebased, never had an issue.
- goalieca 4y agoYou've never used gerrit then. That tool is entirely designed around rebasing with merges as a rare event.
- chris_wot 4y agoYou've never lived.
- Jwarder 4y agoI think it depends on what problems you want git to solve for you. Some people like having the context from the complete the history of little commits without the risks of rebase breaking something. Some people like using rebase to group all changes needed for a feature into isolated(ish) commits. Some people just like the aesthetics of a straight master branch without the clutter of little "corrected typo" or "fixed bug for real this time" commits.
- chris_wot 4y agoThe one thing I'd like to do is to insert a commit between two commits, then edit this and then make a modification. Currently I create a text file, add this, then move this up to where I need to insert it and edit this commit.
- throwaway_au_1 4y agoIt's not clear to me exactly what you mean. Based on adding the text file, which sounds like you're creating a placeholder commit, you might not know about 'git commit --allow-empty' which may serve you better. Not exactly sure of your order of events wrt inserting a commit and editing it (I.e. edit commit message? Or changes?) and modifying it (I.e. see previous) but am happy to try and help if you want to flesh out your example a little more.
- throwaway_au_1 4y agoTo speculate, maybe you haven't heard of fixup/squash. E.g. Commit 1 Commit 2 Commit 3 Using an empty fixup commit, e.g. git commit --allow-empty --fixup=commit2hash You would end up with Commit 1 Commit 2 Commit 3 fixup! Commit 2 Which will adjust automatically (when starting interactive rebase with autosquash) to Commit 1 Commit 2 fixup! Commit 2 Commit 3 You could then simply change the rebase 'fixup' instruction to 'reword' to edit/remove the 'fixup!' part of the message, or 'edit' to continue the rebase uo until that commit and then stop. That said, again, not clear on your use case but maybe that might help you or another reader.
- alisonatwork 4y agoYou can also just `git rebase -i` and set `e` (edit) on the commit before the one where you want to insert a new commit. Instead of doing `git add .` and `git rebase --continue` like you normally would to squash your changes into the commit you've stopped to edit, you can just `git add .`, `git commit -mwhatever` and then `git rebase --continue`. Now you have new commit "whatever" in between the one you stopped to edit on and the next one.
- ludwigvan 4y agoOn Mac, I prefer Gitup, a free and open source GUI which makes rebases (and a bunch of other git operations) much easier: https://github.com/git-up/GitUp https://github.com/git-up/GitUp
- kartoshechka 4y agoirony is that my team use gitlab and we have auto squash before merge, avoiding manual rebasing
- xyzzy4747 4y agoI would recommend not doing anything complicated such as git rebase and just add more commits, patches (git diff / apply), or merges until your code works. If the number of commits is large, it doesn’t really matter. Optimizing for a pretty looking git history is probably the most foolish thing to focus on. If you are doing anything that involves rewriting the history you are doing it wrong.
- k_ 4y agoGood luck bisecting such a repository, unless you squash PRs (for which build passes of course)
- WorldMaker 4y agogit bisect --first-parent bisects only the straight line of first parents of merge commits. If you --no-ff PRs and always have merge commits, it is essentially a bisect at the PR level without any need to squash the graph.
- Nagyman 4y ago> Optimizing for a pretty looking git history is probably the most foolish thing to focus on It's not about "pretty"; commits are a form of _communication_. Do we send emails without editing before hitting send? It's a means to optimize for easier reviews through better comprehension of the changes, which also leads to faster reviews. Our colleagues don't want to read a bunch of intermediate commits. > If you are doing anything that involves rewriting the history you are doing it wrong. Care to elaborate? What's your general strategy?
- chriswarbo 4y ago> It's not about "pretty"; commits are a form of _communication_. Do we send emails without editing before hitting send? Writing clear, atomic commits is a good idea regardless of whether you use rebase or not. In your email analogy, rebasing would be altering previous messages in the chain. That doesn't make rebasing look good! > > If you are doing anything that involves rewriting the history you are doing it wrong. > Care to elaborate? What's your general strategy? Not the parent, but to me the most important part of VCS history is accuracy. Rebasing commits (or cherry-picking them) changes their context; that context can be important for understanding why things were done in a certain way. For example, imagine we're digging through the following history, to understand how some feature 'bar' works: * Add workaround for Error(foo) in feature bar | * Implement feature bar | * Bump dependency baz to eliminate Error(foo) Why was a workaround for Error(foo) added, if that error had already been eliminated? Did that dependency change not work? Is there some more permanent way to eliminate Error(foo)? Is the workaround still needed? Compare that to the following, more accurate history: * Merge |\ | * Add workaround for Error(foo) in feature bar | | | * Implement feature bar * | Bump dependency baz to eliminate Error(foo) | / |/ Here it's much clearer what's going on: the dependency change was not in place when that workaround was added. Hence the workaround shouldn't be needed anymore. Rebasing the 'feature bar' changes on to the 'dependency baz' changes throws away that information.
- dbbk 4y agoEvery PR we have in GitHub is merged with a squash, so I'm kinda missing the value proposition here. Is it really crucial for each commit to be a nice clean unit of work?
- agumonkey 4y agoyou keep the feat branch but only add single merged commit to master ?
- giancarlostoro 4y agoI think it really depends on whose doing the commits, I've mostly worked with people who wont commit things that don't work so you see a lot less commits than you would expect. I prefer commits to be iterative and I prefer to see that if possible. I rather see 100 commits across dozens of files per commit vs 1 commit for 500 files.
- warmwaffles 4y agoDepends on the situation entirely. If I see a ton of commits like "fixing formatting" or "oops", I want those squashed away into proper commits. If the changes you make are atomic in their own right and I can check out that commit, compile it, then run tests, and it passes. That's perfect. It works good for git-bisect, but the trick is to get everyone on board in the project to do that. For public libraries I maintain, it's squash merges all the way. I like a clean history and the ability to check out that commit, compile, test, and run cleanly is perfect.
- giancarlostoro 4y ago> If I see a ton of commits like "fixing formatting" or "oops", I want those squashed away into proper commits. Every team I'm in I strongly advise against such commits honestly. They don't help anyone, I emphasize being able to find things you changed if you need to find them. You can even enforce a format for commits. Funnily enough, I saw a wave of "fixes bug" "now really fixes bug" that got auto rejected by some commitcop utility at a former job, the guy was freaking out cause it wouldnt take all his changes. I guess they wanted to force him to stop doing such awful commit messages. Commit messages should be useful and historically descriptive.
- jbergknoff 4y agoIf I've already reviewed a PR and the author makes further changes, I definitely prefer to review an add-on commit. If the history is rewritten/rebased, then IME the entire PR needs to be re-reviewed from scratch. If we're talking about a <10 line change, then, by all means, rebase to your heart's content. With anything more complicated than that, rebasing a branch that's already been looked at can be disruptive and I'd strongly recommend against it (though squash-and-merge after review is fantastic).
- seba_dos1 4y ago> then IME the entire PR needs to be re-reviewed from scratch Why? What's the difference? You can still diff the previous version of the PR with the current version and end up with the same thing that an add-on commit would give you, but ready to merge as-is.
- Arch-TK 4y agoDoes your project have a policy of compiling and running (and e.g. tests passing) at EVERY commit? I can't imagine being able to easily enforce that without asking people to edit the correct part of their commit. It's maybe more difficult with gitlab/github interfaces where changing the middle of a sequence of commits will not render very well, but in email based workflows it works fine. On the other hand, being able to bisect a project without having to worry about whether an unrelated issue is causing you to traverse the wrong branch of the bisect is an enormous advantage compared to the minimal effort required of keeping track of a modified (rebased) commit in the middle of a set of commits under review.
- mattpallissard 4y agoKeeping your commits as separate units of change, and leveraging rebase/ff-only is worth is simply so you can do stuff like the following. git revert $(git rev-list COMMIT43^..COMMIT123 -- path/to/thing) I've been on teams where everyone _hates_ what a stickler I am about good VCS hygiene until they realize something that looks like it's going to be a big pain in the ass at first glance is doable with a one liner.
- mixmastamyk 4y agoWhat is this a solution to?
- mattpallissard 4y agoReverting a range of changes for a given path.
- Tade0 4y agoNo rebase tutorial is complete without the --onto option, which lets you essentially transplant a series of commits to a completely different branch. Very useful when you've created a branch(A) based on another branch(B), which in turn was based on master, but in the meantime master had a few commits added, so while it's trivial to rebase B with master, rebasing A with an updated B won't work.
- b3morales 4y agoThe latest git release has an option to handle this multiple branch scenario for you: `git rebase --update-refs` I don't know why I can't find any announcement of this other than a GitHub blog, but here it is: https://github.blog/2022-10-03-highlights-from-git-2-38/ https://github.blog/2022-10-03-highlights-from-git-2-38/
- bern4444 4y agoIs that effectively the same as cherry picking a bunch of commits at once?
- vincentkriek 4y agoI sometimes run into rebases where solving merge conflicts 3 times is hard. Replaying 3 commits for instance, where merge conflicts are present in each one. In the first I need to fix the merge conflict but remind myself that there are more commits following this that change this behavior. With a merge commit I am fixing the resulting work on both branches, which is easier than merging the in progress state in the current branch.
- tcoff91 4y agoIn these scenarios, I think it's better to use merge commits. Anytime resolving conflicts becomes pretty intense, where you're feeling like there's a significant risk of introducing a bug in the resolution process, I think it's better to use merge commits because then it's preserved in the merge commit how the merge conflict was resolved. If things were done incorrectly, you can trace it back to the merge commit and analyze it and you don't potentially lose important intermediate state that you might need to recover. On the other hand, If you're touching the same code in 3 separate commits, then perhaps they shouldn't be separate commits. In these instances, I often do 2 rebases: 1 to squash the commits without reparenting them, and then another to reparent the squashed commit onto the upstream branch. Also, if you use merge commits for merging PRs, it's easy to cut through the noise of the commit graph by using git log's --first-parent option. Once you are using this, it's a lot less important to keep an ultra-tidy commit graph.
- abeyer 4y agoIsn't that exactly what rerere is for?
- manbash 4y agoAnyone who has experienced rebasing a PR on github knows how much it hurts the review process.
- derefnull 4y agoIn other words, GitHub has useful tooling that breaks when commit history is rewritten
- sidlls 4y agoGit is in general a terrible tool: I’ve always thought of it as a shining example of where “worse is better” ought to have been applied. Rebasing is one of its worst features. For non-trivial changes, anyway, it is often just a way to add complexity and messiness to what should be a simple workflow. And the benefits aren’t at all as clear as its advocates contend.
- mixmastamyk 4y agoYes, and these folks are never around when you try rebase and get a forty file conflict and have no idea how to get out. Happened to me several times when I fell for one of these articles. You know what works almost every single time? With tiny conflicts if any? Merge + squash on gitlab.
- Extigy 4y agoIf a rebase goes wrong and you want out you can run, git rebase --abort to return to where you were beforehand. I find that git is actually very good at explaining what is going on and what you should do next by just running git status in the middle of some process like rebasing and reading what it says. Even if it all goes really wrong the git reflog has always saved me.
- mixmastamyk 4y agoOk, but what do you do when it goes wrong every single time you've tried it? That's what happens at work, so I gave up and use merge+squash on gitlab.
- sidlls 4y agoYep. And most of the time conflicts merging from master into your working branches produces minimal conflicts. Rebasing is just a way to make extra work for yourself
- flippinburgers 4y ago1) Never use rebase on the master branch. 2) Before you rebase take a note of your current branch's HEAD commit. 3) If things go horribly wrong, you can force your branch to point at the original commit and it will be as if nothing happened. Well as long as you do it immediately. At some point git gc will collect up unreachable commits and delete them.
- zwieback 4y agoYears ago I really liked rebase, now I never use it. I don't know why, though, one of those mysteries of the brain.
- tuckerpo 4y agoI love rebase. It allows for a Draft PR workflow where you can have your WIP out in the open for a big project, and then clean it all up via rebasing right before asking for reviews. Just don't rewrite history on master. :^)
- itslennysfault 4y agoA lot of people have hate for rebase, but I've always LOVED it. I've always had way less issues with it than merge. Whenever I do a feature I work in a feature branch then just rebase it with the target branch (main) before submitting the PR and it is a really painless workflow I've used for years.
- rmetzler 4y agoI really try to like git rebase, especially git rebase -i and at one time I even used a special tool to help with that. What I find is that I see a lot more merge conflicts than in Gitlab MRs, but it could also be that the tooling on my machine is suboptimal: switching between VSCode as the editor and using vim in a separate terminal for git. In vim I don’t see the current commit where the conflicts appear.
- BeFlatXIII 4y agoI made some minor contributions to MuseScore a few years ago and they turned me on to the joy of rebasing.
- rmetzler 4y agoI was waiting for „Gitlab releases a UI for rebase -i in MRs“.
- dnsmichi 4y agoThanks, great idea. Added a comment into the feature proposal in https://gitlab.com/gitlab-org/gitlab/-/issues/273250#note_1127147192 https://gitlab.com/gitlab-org/gitlab/-/issues/273250#note_11... - suggest upvoting and/or subscribing to notifications.
- perryizgr8 4y agoRules I would have everyone follow if I was a dictator: 1. 1 PR, 1 commit. 2. 1 PR cannot have more than 50 lines of product code added. Any number of lines can be removed. You can have up to 100 lines of test code. 3. Every PR should include a set of tests for the added/changed functionality. They must pass. 4. Git merge is forbidden. Everyone must rebase. 5. Every PR goes into master. Nobody can push to master. You can create as many feature branches you like, but definition of done is that your code is available on master. 6. Identify relevant existing test cases and make sure they are passing. 7. Master must always be in a state that it can be deployed instantly.
- lamontcg 4y ago> 1 PR cannot have more than 50 lines of product code added. Any number of lines can be removed. You can have up to 100 lines of test code. Hard disagree. Landing a single class/module to implement new functionality may take more than 50 line of code and 100 lines of test, even though conceptually the additional functionality is simple and it amounts to mostly boilerplate and looks like every other class that implements the pattern. Some large plumbing refactorings or CI refactorings are difficult to do in small chunks. I'm perfectly fine with a PR that replaces one internal API with another one and then has hundreds of small copypasta fixes littered around the codebase to swap out the APIs. Anyone should be able to read that without cognitive overload. Tests are also commonly over 100 lines of code since they tend to be repetitive by nature, and I'd like to not see those artificially broken up into smaller PRs since the most important question I've usually got is if all the cases are covered or not. Breaking 300 lines of tests up into 3 different PRs to satisfy some kind of line-length metric means now the most important question I have needs looking at all 3 simultaneously and that is deeply counterproductive and totally useless. And small code changes with lots of comprehensive tests which fill out cross products of different API usages are great and should be encouraged. And while I don't personally like the dozens-of-tiny-atomic-commits approach, I deeply don't care if other people do it or not. I've never found it useful to read their PRs, or even after the fact, but I won't stand in the way of them doing that if it is what gives them enjoyment (OTOH, I never do that).
- AtlasBarfed 4y ago
- DBCerigo 4y agoA much more in-depth, advanced, and more valuable imo, article on the same topic https://medium.com/@porteneuve/getting-solid-at-git-rebase-vs-merge-4fa1a48c53aa https://medium.com/@porteneuve/getting-solid-at-git-rebase-v...
- bob1029 4y agoRebase is something that I see a lot of developers shy away from but it is usually the right way to get a feature branch re-aligned. My practice is to rebase all my pending PRs each morning to make sure that the prior day's activity is coalesced. If you wait weeks and weeks to do the first rebase for a big change set, you can wind up visiting the same files and conflicts way more times than is logical. In my experience, this results in a much greater chance of screwing something up along the way, further reinforcing for some developers that the rebase is bad. Timely rebase is the answer.
- hoten 4y ago--fixup has been incredibly useful for my rebase workflows.
- MilStdJunkie 4y agoIn my personal experience rebase made ISO9000/AS9000 gatekeepers twitchy. Even to the extent that they'd tell the Overlords "Do everything in Perforce, or else". And then the Overlords shut down all the VCSs because "this isn't a software company". Then everyone sneaks around using weird homebrew portable tracking widgets, or, more often, just gives up. Is rebase handy? Oh yeah.
- divbzero 4y agoThe following tip from OP could be rather useful. git rebase --exec 'make test' main The --exec <command> flag allows you to run any shell command after each rebased commit, stopping if the shell command fails (which is signaled by a non zero exit code).
- nickporter 4y agoLove rebasing, love merging, squash or no squash, it all depends on what I'm trying to communicate with my pushes. Just discovered the --rebase-merges option, worth exploring if you want to edit a commit under a merge commit, but don't want to mess up the merge commits.