7aymfa
95.51K
· October 2012 ·
10534 128567884189 828694189 2287781 3877042 n

Please, oh please, use git pull --rebase

git

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.

Sign in or sign up to add your response.

34 Responses

384
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

over 1 year ago ·
394
10534 128567884189 828694189 2287781 3877042 n

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

over 1 year ago ·
5998
7f4d3c86c71614d8c709dcb51c88c3ac

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

over 1 year ago ·
6000
Cc1482b6867895fb0cc52063dc2b60e9

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

git config branch.autosetuprebase always

As explained by khasinski

over 1 year ago ·
6016

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'.

over 1 year ago ·
6017
9cecfc695240b56e5d3c1a5dc3830967

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

over 1 year ago ·
6050
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.

over 1 year ago ·
6051

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

over 1 year ago ·
6052
294765 10150330995983461 21950553 n sq

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

over 1 year ago ·
6053
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.

over 1 year ago ·
6054

git is overcomplicated.

over 1 year ago ·
6056
B6e666ac45ee856f0dcd07da8dfb30e2

clockworkelves, life is overcomplicated too.

over 1 year ago ·
6060
1e73756560928ccc53ee5a4410715e57

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

over 1 year ago ·
6062
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')
over 1 year ago ·
6063
10534 128567884189 828694189 2287781 3877042 n

clockworkelves

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

over 1 year ago ·
6065
A784456bf9c7902bec153445c50f015c

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

over 1 year ago ·
6067
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.

over 1 year ago ·
6070
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?

over 1 year ago ·
6074
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.

over 1 year ago ·
6080

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.
</rant>

over 1 year ago ·
6081
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.

over 1 year ago ·
6227
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.

over 1 year ago ·
6230
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.

over 1 year ago ·
6232
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.

over 1 year ago ·
6468
David

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

over 1 year ago ·
8510
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.

over 1 year ago ·
8516
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.

over 1 year ago ·
10408
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?

over 1 year ago ·
13976
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.

over 1 year ago ·
17584
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

over 1 year ago ·
17882
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.

over 1 year ago ·
18285
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

over 1 year ago ·
18349
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?

over 1 year ago ·
20107
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?

over 1 year ago ·
Featured Programming Job

Solutions Architect, Enterprise Informatics
·
Boston, New York, or Portland, OR
·
Full Time
Search all programming jobs