Where developers come to connect, share, build and be inspired.

32

Please, oh please, use git pull --rebase

87972 views


When working on a project you usually synchronize your code by pulling it several times a day. What you might not know is that by typing

git pull

you actually issuing git fetch + git merge commands, which will result with an extra commit and ugly merge bubbles in your commit log (check out gitk to see them).

It's much better to use

git pull --rebase

to keep the repository clean, your commits always on top of the tree until you push them to a remote server. The command will apply all your yet-to-be-pushed commits on top of the remote tree commits allowing your commits to be straight in a row and without branches (easier git bisects, yay!).

Few notes though. If you want to merge a feature branch it might be wiser to actually merge your commits thus having a single point of integration of two distinct branches.

Also the conflict resolving will be now per commit basis, not everything-at-once, so you will have to use

git rebase --continue

to get to the next batch of conflicts (if you have any).

NOTE: Because of many discussions about this note. I DO NOT encourage rebasing remote (public or shared) branches. Rebasing local history is OK (it's more than OK, it's sometimes necessary to maintain a clean history), but changing other people commits history is considered a bad practice.

Comments

  • User-avatar

    The problem with rebase is that it corrupts the true history of the commits. This doesn't show up on a smaller repo, but if you have a busy repo, with lots of contributers, untangling a mess becomes much harder if you no longer have the true parentage of a given commit.

    Git rebase destroys the context of the commit, leaving basically a diff apply instead of the much more contextually rich merge commit. Yes, your repo looks messier, but it more accurately reflects the lifecycle of the code, and what the developer intended at each commit. If you really want a straight-line for your repos, why aren't you using something like SVN? Is the distributed nature of git really the big selling factor?

    I've run teams that have used git how you are describing, always making people use rebase (in this case it was because we were syncing to SVN). Reconstructing what a developer did 4 months ago is much simpler with a merge vs a rebase. You can go to the merge just before the developer's first commit and see what the repo actually looked like when they started work. You can never do that with a rebase. The context in which the developer was working has been lost. Also, with multi-commit branches, you can see what the repo looked like after each commit. With a rebase, those intermittent commits are almost useless, as the repo doesn't look like it did when they made that commit.

    To sum up, don't subvert git just because you want to see a straight line in your commit graph. It's not worth it, and it is ultimately a lie.

  • Cc1482b6867895fb0cc52063dc2b60e9

    It's a lot easier to just set rebase as the default using

    git config branch.autosetuprebase always
    

    As explained by khasinski

  • 10534_128567884189_828694189_2287781_3877042_n

    rconklin

    It's a popular misconception that git rebase destroys history. It rearranges it into something else. Context isn't as important as you might think and rebase is a tool for LOCAL rewriting of history, not REMOTE rearrangements. That's the basic difference between SVN-likes and a distributed VCS.

    Remember - you're only rebaseing your own code, often on a feature branch. It's your own history (until you push it somewhere).

    If you don't understand that you're going to have a bad time with any DVCS and have ugly, hairy history that is basically unreadable to anyone bisecting, looking for bugs.

    It's your option (feature branches with merges) that's available to SVN users. Making history useful is something available only to DVCS.

    Don't limit your git to a subversion clone with better merging, produce useful commit history.

  • User-avatar

    git is overcomplicated.

  • User-avatar

    I never use 'git pull'. The reason is that I want to fetch - look at what other people changed, and only then decide whether I'd like to rebase to those changes now, while I'm doing my stuff locally.

    So my advice - unless you know exactly what you are getting from the remote branch, don't use 'git pull'.

  • User-avatar

    No - I want to see the full history. No rebase please.

  • 294765_10150330995983461_21950553_n_sq

    I prefer to git fetch then git rebase (or merge if appropriate) manually.

  • 32fc08ee80cf129f6b1e8593eccb9a03

    I use git pull --ff-only (aliased as git p) so if the pull is anything other than a fast forward I have to stop and think about what I want to do about it. Rebasing when I think I'm going to fast forward is not a behavior I want. If I decide a rebase is really what I want I have a git prb alias too.

  • 38d766f23d544ca258e4fe2110104c16

    +1 for not using git pull. Use git fetch, and then decide on the appropriate action.

    In addition, I don't commit or merge onto master (or any shared tracking branch) until I'm ready to push, so I very rarely have a fetch that isn't a fast forward anyway.

    I do tend to rebase my development branches.

  • 1e73756560928ccc53ee5a4410715e57

    Please don't use rebase if other people rely on / pull from your codebase; use merge instead.

  • Bc7e893b6d4605000478c871b7ce8862

    @randgalt - You want to see every burp and hiccup along the development timeline? Why not take that viewpoint to the logical endpoint and auto-commit after every character typed?

    Oh would that be insane? Because it's useless noise in the history? What you actually care about was the developers intent? Now you're starting to see the light. Once you grok git you realize the value of crafting your local commits to provide an immaculate and bisectable project history to the outside world.

  • 10534_128567884189_828694189_2287781_3877042_n

    montas

    Because sometimes you can work on something for a couple days and you don't want to diverge so much from the original branch. Keeping codebase synchronised is often cheaper than solving lots of conflicts when you want to push.

  • 10534_128567884189_828694189_2287781_3877042_n

    @losinggeneration

    git pull --rebase locally and then pushing to remote branches won't change anyone's history except yours. :) It's OK to do it. In fact - you should do it. Are you talking about people pulling using public (remote) branch (resolving pull requests)? Pull requests should demand that the said code apply in a clean manner (demand rebasing PR code against current HEAD) and use merge -no-ff option to indicate resolved request.

  • 10534_128567884189_828694189_2287781_3877042_n

    You can get even shorter version as I described here: http://coderwall.com/p/yf5-0w

  • B6e666ac45ee856f0dcd07da8dfb30e2

    clockworkelves, life is overcomplicated too.

  • 10534_128567884189_828694189_2287781_3877042_n

    clockworkelves

    Check man git, you'll see it's 'the stupid content tracker' ;)

  • 10534_128567884189_828694189_2287781_3877042_n

    @losinggeneration It's about git pull --rebase, not any other kind rebasing. It's pretty clear it's local. ;) But I'll add a notice to the original note.

  • 1dc73b4f365e6a0ed645d960b496d418

    Well I'm embarrassed. I had to facepalm myself when I realized the issue I was seeing was from people doing a rebase of master from a branch and then pushing (which is where issues really crop up from the history being changed.) So you're quite right. Can I just blame it being too early in the morning ;) I'm going to retract (delete) my above comments.

  • Ab927485bccfcf35ba4583723876063f

    From git pull --help:

    This is a potentially dangerous mode of operation. It rewrites history, which does not bode well when you published that history already. Do not use this option unless you have read git-rebase(1) carefully.

    I would rather have a safe and acturate history then a clean but incorrect history. I would never work with anyone that just uses rebase willy-nilly. And you do never actually have to use it, or at least I have never seen any such case.

    I would not even use it on a private personal repository.

  • 10534_128567884189_828694189_2287781_3877042_n

    Pull with rebase wont push changed history unless you have multiple remote repositories in which case you should know git better. You never have to use rebase, you can always do a revert commit. But it makes your repositories unreadable and sharing code so much more difficult.

  • Userpic

    oh, i didn"t knew you could do that. i was doing the same thing in a slightly more verbose way:

    git fetch
    git rebase origin/my-branch
    

    great advise, thanks

  • 7f4d3c86c71614d8c709dcb51c88c3ac

    I tried explaining this to a colleague of mine about two years ago and he simply couldn't understand.

  • 9cecfc695240b56e5d3c1a5dc3830967

    Rebase by default when doing git pull: https://coderwall.com/p/tnoiug

  • 362ca0fc6577ca2487edea6a9b0682f9

    case 1: I want to push my code changes only (no merges), and I my local branch is out of date

    • git pull –r (or pull - -rebase)

    case 2: I need to push a merge I just did, and I my local branch is out of date

    • git pull (If you have 'git pull' aliased to 'git pull -r', then 'git pull --no-rebase')
  • A784456bf9c7902bec153445c50f015c

    And if you are lazy to do git fetch & git rebase you might use https://github.com/aanand/git-up

  • 31474fc2498303a486f57d623fabdc89

    why would you git pull before you want to push?

    You pull something, work on it, and when you are done, then you pull, check if everything is working and push.

    Why would i resolve problems with remote changes multiple times a day if i'm not done with what i'm working on?

  • David

    I'm a huge advocate for using git fetch and then deciding upon relevant action.

  • 7dedb03c52d9b14738f844c799b2dbc4

    If you are working in a branch with a friend, a think git pull --rebase is the must. But when finish the fix/release, i recommend use fetch and merge.

    git pull --rebase is really a #protip, but exist a specific times to use it.

    Anyone agree?

  • 2a3c94bbf645e76c0f8a727abae35b7a

    Personally, I follow a simple rule to both keep my history clean and retain commit parentage. When I'm merging a new branch for the first time, I rebase and do a fast-forward merge. If it happens so that the issue is still not done, I continue working on that branch and all subsequent merges are --no-ff without rebasing. So, all branches maintain continuity through the commit log (basically, it remains a single chain of commits) without crowding it with petty one-commit "made the copyright font size 0.1em smaller" branches, that take twice as much space in the best case (in the worst case they are based on a commit a few weeks ago and take quite some scrolling to figure out what they are).

    Aside from that, I pretty much adhere to Git flow, having master and develop branches, as well as the occasional ones for hotfixes and releases.

  • 808e1f311009f0e3e3115136775830db

    I agree with @rconklin, rebase is a useless lie; on top of which it can introduce dumb merge conflicts in some cases. If you want to look at a pretty straight line of commits, just do git log --no-merges

  • None

    I don't normally use git pull myself rebase or otherwise. What I do often on my feature branch is git rebase origin/master (or whatever the shared development branch is) to make sure I am working on the correct level of code. Last one in is the one responsible for making sure code works with existing.

    It would be helpful to note that the branches are generally short lived and not super all encompassing in code changes usually.

  • Ijoshftw512

    If you have Ruby:

    $ gem install git-up
    ~/myrepo $ git up
    

    It rebases by default and pulls all your upstream branches instead of just your current one. Also, colours, yaaay!

    https://github.com/aanand/git-up

  • None

    Surely the right thing is to have the commit log store all information (not hiding it by rebasing), but have better tools for simplifying the log when you view it?

  • None

    Having used both Git and Svn, I see the beauty of maintaining a linear history and yet appreciate the beauty of branching and merging. I understand that there is no absolute right or wrong with either approaches but I feel that there is a right time to rebase and a right time to merge.

    Eg. if a team of two or more works on a single feature branch, I would get them to rebase their commits on top of the latest remote feature commit. This is to maintain a linear commit history on the feature, The benefits of doing this in my opinion is that it becomes easier to code review their changes for that particular feature and see what each dev has done.

    To keep things simple and avoid fixing a massive pile of conflicts, we would merge from develop to the feature branch every now and then to ensure that changes from other teams are integrated with the feature(maybe daily). When the feature is complete, it is merged back with develop.

    What are everyone's thoughts to this hybrid approach?

  • None
  • None
  • X3vh8hrx_normal
  • X3vh8hrx_normal

Add a comment