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

5

'git pull' is evil!

8952 views


Avoid using git pull, unless you're the sole owner and user of the repository.

A git pull works by doing a git fetch followed by a git merge. This is OK if your local branch is in sync with the remote branch. Otherwise, the git merge will result in a commit graph that looks like a spaghetti because it will do a merge of your local branch with the remote one.

A better approach is to use git fetch followed by git rebase.

Say that you're synchronising your master branch. Do a git fetch and git rebase origin/master.

That will find the earliest common commit between master and origin/master, move to a temporary space everything in your local branch that comes after that, fast forward it to the latest commit on origin/master and then apply each of the commits that were put aside on top of it, one by one, stopping if conflicts are found so that you can fix them before going on with the rebase.

Confusing? It might be at first, but once you get the hang of it, you'll wonder why you've been using git pull all this time.

More info on stackoverflow.

Update: As pointed out by @jwebcat, there are cases (specifically when rebasing a merge commit) when this approach might be a shot in the foot. Please read his protip for more information.

Comments

  • Transparent-large

    Don't forget about git pull --rebase as shorthand for the approach you describe here, too

  • Richhealeyavatar

    Urgh, unless your history has been published.

    Blanketly telling people to use one or the other is stupid.

  • 142f56fa109167d398a312e968485087

    I'm using an useful configuration like below:

    git config --global pull.rebase true
    
  • 70e1167dbde5397557b0ec6fabb3d90a

    Yes! Finally we can all take a moment for the death of git pull.

    I highly recommend using rebase -p to preserve merge commits though.

    I have written a protip follow up on this tip

    update above

    I will write a follow up pro tip and reference yours.

  • User-avatar

    A few clarifications that should have been obvious by reading the tip, but it seems I'm failing a bit in communicating. :)

    1 - I'm talking about work in one branch, not between branches.

    2 - If you fetch before you rebase the branch onto its own remote branch, you won't ever alter whatever history is already in the repo.

    @jwebcat: Thanks for the tip, I'm updating mine to reference yours as well.

  • 9ce93e41c69b4e4ea8afce22cf11e2f4

    I've tried to give a balanced comparison of merge and rebase here: https://coderwall.com/p/ny1hia

  • 985347f8d4d896aa17a3984d40971038
  • 70e1167dbde5397557b0ec6fabb3d90a

    @markushausammann As the author points out, please read the article again.

    A good rule of thumb: rebase from master onto feature branches and merge feature branches back to master.

    To stay updated rebase changes from upstream onto master.

    What you have to be careful of, is, do NOT rebase the history you have already pushed upstream. That's all.

    Only fetch changes from upstream. Then rebase onto master. After that, rebase master onto any branches that you have made.

    Just follow this model and make friends with rebase. Have a read @havvg wrote a great article on rebase.

  • 70e1167dbde5397557b0ec6fabb3d90a

    @richoh I agree completely see my comment above.

  • 56332b2b625a345559a0b77b6a01903f

    According to this information here: http://stackoverflow.com/questions/3357122/git-pull-vs-git-fetch-git-rebase you should probably edit or even remove your tip. It looks like it will create a lot of confusion and some trouble.

    You should never use the rebase approach if someone else has already pulled from your master branch.

    And when can you be sure that this is not the case?

  • 31474fc2498303a486f57d623fabdc89

    You are quoting stack overflow post that say you should never use this approach unless you are sure that nobody pulled from your branch. This post is really confusing.

    Also I guess you should not merge your develop directly to master but rather use release branch for that.

  • User-avatar

    This post seems to be causing a lot of confusion, so let me make this clear: I am not, in any way, advocating that you should always use rebase instead of merge. If you thought that, then please re-read this tip's title and you might get the clue.

    By using this proposed approach, you will never change any history that's already been publicised. You're rebasing your local changes on top of whatever is in the repo. The whole point of this tip is for you not to publicise messed up history, or as I like to call it, a spaghetti.

  • 5bbb7d9ecc1f4fe80ac5580c2fd07113

    And what do you guys think of the git-flow approach? I haven't used it yet but it seems I'm gonna give it a go on my next project. http://jeffkreeftmeijer.com/2010/why-arent-you-using-git-flow/

  • User-avatar

    @manuite: I like git flow. I don't think that it's the best for everyone or every project, but it's still a great reference.

    I personally use flow or some variation of it in most of my projects, and it helps to keep things organised.

  • 16d031b5434f37b1128f4c498666f074

    Thank you @jugyo and @nevir - git pull is hardly evil if you use it properly.

  • 10ca55864735b3ccefb16bd93a1596a7

    @cassianoleal @jwebcat This is bullshit. Git-pull is not evil at all, nor it is dead. All it does is a fetch and a merge in one go. If you find yourself fetching and merging often without changing anything in the process (and this WILL happen, if you update repos or branches you've not worked on for example), why not using git-pull ?

    Also, merge commits aren't meaningless, even when merging your upstream branches. They're still commits and as such, they have all the informations normal commits usually have: parents (2 or more for a merge) so that you have a track of what was the repo's state when the merge has been done, a commit message, an author and commiter date / name / email, a reflog identity, they can provide you with stats and diff (and therefore patches) and, most importantly, they're bisectables.

    @manuite I use git-flow on a daily basis and it's really a good model. Don't get too excited about hotfixes though, they should be used only rarely ;)

  • User-avatar

    @likeyn -- Obviously, the article's intention was to call the attention to the inherent danger of using git pull blindly. I understand that many people feel very attached to their way of doing things, but that shouldn't hinder contextual and subjective evaluation.

    If you understand what git pull does, and you know that that's what you want at that moment, by all means use it! The problem I see is that many people blindly use it when they should actually be rebasing their local commits instead of merging (or even doing something else altogether), leading to an incomprehensible spaghetti commit graph, that's neither true to everyone's intention, nor bisectable.

    Also, a minor correction: not all "normal" commits (whatever this is supposed to mean) have two or more parents. Most have only one, and there's the first commit that has none. :)

  • 70e1167dbde5397557b0ec6fabb3d90a

    @likeyn don't get too excited yourself bud!

    This article was meant for people that just use git pull without really realizing if that's what they really wish to do,

    Like @cassianoleal replied above, if you know what you are doing, then by all means git pull to your hearts content.

    HOWEVER-- this article is very valid and IS VERY FAR FROM BULLSHIT.

    Best to you mate , cheers :)

  • 10ca55864735b3ccefb16bd93a1596a7

    @cassianoleal Ha, yeah thanks for pointing out that commit parents mistake. Edited :)

    A spaghetti graph is perfectly bisectable, and does not lie about when you've committed changes or merges. I don't see the problem with using git-pull blindly; that's the safest way to go if you're a begitnner or don't get or don't need to get (yet) what git is all about.

    The only drawback that seems to be valid is that git-pull does not produce a "linear" history graph but hey, that's exactly what Git wasn't made for. Git tries very hard not to mess up with your history and therefore has made merging changes easy; if you do rebase your upstream branches it seems to me you'd better use SVN instead as it's exactly the way SVN works and what Git is trying to avoid IMHO.

  • User-avatar

    @likeyn I see your point about using it blindly before you understand how git works and it's a valid one.

    rebase is even more dangerous when people realise they can git push -f what they've rebased, and that's the main reason why I usually let (and even teach) people use git pull blindly when they're getting started.

    I know, this might sound contradictory to the article, but I believe that whoever gets here is either someone who's already curious enough go deeper, or will be intrigued enough to start digging.

  • 10ca55864735b3ccefb16bd93a1596a7

    Even if you're an advanced git user, git-pull is perfectly safe whereas git-rebase is not. If you're updating a branch you're working on, you'll most likely want to fetch and check the changes before merging. But even if you don't, you can undo a blind git-pull with no harm to your repository nor your history by doing a simple git-reset (--hard or whatever option you need).

    @cassianoleal @jwebcat I apologize for being a bit aggressive. All I wanted to say is that git-pull is absolutely not evil, nor dangerous, nor dead; and git-rebase is a nice tool for special cases but I can't see any reason why it should be a better approach than git-pull / git-merge.

  • User-avatar

    @likeyn -- no apologies necessary, no hard feelings here.

    I understand your points, and I think they're pretty valid. My own experience has led me to the path of advocating for rebase instead of pull/merge in most cases, but maybe that's just because of mine and my team's specific workflow.

    The comments on this protip is a heavy indication that there's plenty of uses for both (all) approaches. I always hope that people will make decisions taking into account their own reality, instead of following protips or other advices blindly. Worst-case scenario, people will learn from their own mistakes. :)

  • 4c6882ebdcd123f924267f54c6d74196

    @cassianoleal "I know, this might sound contradictory to the article, but I believe that whoever gets here is either someone who's already curious enough go deeper, or will be intrigued enough to start digging."

    That describes me perfectly. I, however, feel that it's important to let a beginner know to use git pull as often as possible until they understand a bit more (especially because they very likely will learn git push -f). Although I'm at the point where I'm digging deeper and beginning to understand git more and more, there will be others that get to this page/article who are at the very beginning in terms of using and understanding git.

Add a comment