167

When you run git pull on the master branch, it typically pulls from origin/master. I am in a different branch called newbranch, but I need to run a command that does a git pull from origin/master into master but I cannot run git checkout to change the selected branch until after the pull is complete. Is there a way to do this?

To give some background, the repository stores a website. I have made some changes in newbranch and deployed them by switching the website to newbranch. Now those changes have been merged upstream into the master branch, I am trying to switch the website back to the master branch as well. At this point, newbranch and origin/master are identical, but master is lagging behind origin/master and needs to be updated. The problem is, if I do it the traditional way:

$ git checkout master
   # Uh oh, production website has now reverted back to old version in master
$ git pull
   # Website is now up to date again

I need to achieve the same as above (git checkout master && git pull), but without changing the working directory to an earlier revision during the process.

BartoszKP
  • 34,786
  • 15
  • 102
  • 130
Malvineous
  • 25,144
  • 16
  • 116
  • 151
  • @phi: I don't think it would work, because I'm in `newbranch` and there's nothing there to stash! – Malvineous Sep 25 '13 at 01:19
  • I would clone into a fresh directory, merge newbranch into master, merge master back into newbranch, then git pull from where you are. Master and newbranch will be the same. – aet Sep 25 '13 at 01:23
  • @aet He could just do that now in his current directory by doing `git fetch; git merge origin/master` from within `newbranch`. There is zero benefit to cloning an entire second copy of the repository. – user229044 Sep 25 '13 at 01:28
  • Upstream has already done a fast-forward merge on `master` so `newbranch` and `master` already are the same. The problem is I can't switch to the `master` branch without going back a dozen commits (losing many files in the working directory) and then doing a `git pull` (restoring things to the state they are in now.) – Malvineous Sep 25 '13 at 05:50
  • 3
    closely related: http://stackoverflow.com/questions/3216360/merge-update-and-pull-git-branches-without-using-checkouts – Ciro Santilli OurBigBook.com Aug 11 '14 at 15:28
  • I found the answer that worked for me in another stackoverflow post: http://stackoverflow.com/questions/3216360/merge-update-and-pull-git-branches-without-using-checkouts Basically: `git fetch :` – koral Sep 10 '14 at 22:55
  • Maybe consider changing the accepted answer to mine below? – Thomas Feb 07 '17 at 18:34
  • 2
    Possible duplicate of [Merge, update, and pull Git branches without using checkouts](https://stackoverflow.com/questions/3216360/merge-update-and-pull-git-branches-without-using-checkouts) – Kyll Aug 02 '18 at 10:19

8 Answers8

203

Straightforward: Updating from a remote branch into a currently not checked-out branch master:

git fetch origin master:master

where origin is your remote and you are currently checked out in some branch e.g. dev.

If you want to update your current branch in addition to the specified branch at one go:

git pull origin master:master
Kyll
  • 7,036
  • 7
  • 41
  • 64
Martin Peter
  • 3,565
  • 2
  • 23
  • 26
  • 5
    Hm, it seems it doesn't always work, though; I just got prompted to merge with my WIP branch. – underscore_d Sep 01 '17 at 11:35
  • @underscore_d same for me. – Greg Oct 12 '17 at 17:49
  • 1
    Worked for me...if it prompts to merge then I imagine there are changes in your branch that you are updating that are not committed to the origin – skim Nov 28 '17 at 14:52
  • 2
    How is this supposed to work? It doesn't work for me, it just tries to merge origin/master into my currently checked-out branch. – mhogerheijde Mar 26 '18 at 14:18
  • 4
    This pulls master into the current branch. This is definitely NOT what is being asked for. If you change pull to fetch, then this would be exactly what is being asked for. – Jeff Wolski May 11 '18 at 13:28
  • is `git fetch origin master:master` going to overwrite local `master` branch with the remote version no matter what or there is some kind of protection that blocks you from doing it if the change is not fast-forward? – pqnet Aug 30 '23 at 07:20
105

This is answered here: Merge, update, and pull Git branches without using checkouts

# Merge local branch foo into local branch master,
# without having to checkout master first.
# Here `.` means to use the local repository as the "remote":
git fetch . foo:master

# Merge remote branch origin/foo into local branch foo,
# without having to checkout foo first:
git fetch origin foo:foo
Community
  • 1
  • 1
Thomas
  • 2,131
  • 2
  • 20
  • 23
  • 3
    This is the best, as it works with uncommitted local changes. – Tomasz Gandor Jan 20 '16 at 14:04
  • 3
    If you just want to catch up with the latest changes you'd do `git fetch origin master:master`. `git fetch` by itself would assume you meant to update the current branch and not some other branch. – John Leidegren Feb 22 '17 at 12:06
  • 3
    This is the simplest and most direct answer. This should be the accepted answer IMO. – Keego Apr 14 '17 at 01:10
  • @JohnLeidegren - except it does not always work as intended. See comments to https://stackoverflow.com/a/42902058/274579 answer. – ysap Dec 23 '19 at 15:55
24

As it turns out, the answer is deceptively simple:

$ git fetch                           # Update without changing any files
$ git branch -d master                # Remove out-of-date 'master' branch
$ git checkout --track origin/master  # Create and check out up-to-date 'master' branch

This allows you to update the master branch without switching to it until after it has been updated.

Malvineous
  • 25,144
  • 16
  • 116
  • 151
  • 12
    This doesn't do what you asked how to do. – jthill Sep 25 '13 at 08:09
  • As the comment above says, the question you wound up asking isn't really the question you wound up having answered. You should update your question so that it's less specifically about merging into a branch without checking it out, and more about moving directly to the newest version of a branch available on a remote without checking out the old version first. – user229044 Sep 25 '13 at 12:02
  • My question was about how to do a pull before a checkout, which is what this achieves. I will edit the question for clarity but having re-read the question, this answer does exactly what I asked! – Malvineous Sep 26 '13 at 01:09
  • 1
    It's absolutely the answer I came here looking for :) – Sophistifunk May 07 '15 at 22:40
  • 1
    Not what OP wanted, but helped me, to be honest. – Marcel Bro Dec 16 '15 at 17:02
  • Fixed in my case. Thanks – zono Mar 05 '16 at 20:26
  • 1
    @anoniim, not what the OP wanted? You mean the OP that just answered this question? – smac89 Sep 13 '17 at 03:30
  • Thanks! I was looking for a(n IDE-friendly) command that I can use right after the merge request of my feature branch is merged in GitLab :-) – mike Apr 11 '19 at 06:56
12

You're worried about something that cannot be fixed, as Git operations are not atomic. You will always have a hole where your working directory is half way between branches, even if you update master without first switching to it. This is why Git is not a deployment tool.

Since you're not actually committing code in your production environment (I hope), you don't actually need to have a branch checked out. You can simply do a git fetch to update your remote refs, and then git checkout origin/master to move the working directory directly to the commit currently pointed to by origin/master. This will put you in a detached head state, but again, as you're not committing code, this doesn't matter.

This is the smallest hole you're going to get, but as I said, a hole still exists; checkout is not atomic.

user229044
  • 232,980
  • 40
  • 330
  • 338
  • I understand the limitations of using git for deployment, the problem is that the hole in this case is going to be minutes long instead of less than one second. Nice idea about checking out `origin/master` though, that might just do the trick. – Malvineous Sep 25 '13 at 05:43
  • What makes the hole "minutes" long? Pulling data across the network? Just do a `git fetch` before you do anything else and get the actual transfer of data out of the way. – user229044 Sep 25 '13 at 11:58
  • It's minutes long because a (now) untracked file would be overwritten by an earlier commit. So I have to copy the file, do the git stuff, then put it back. The 'minutes long' comes from my typing speed. (Yes I could script it but it was just to make a point that having git do everything itself is faster.) – Malvineous Sep 26 '13 at 08:38
4

You can use update-ref for this:

git fetch
git update-ref refs/heads/master origin/master
git checkout master

Note that this would throw away any local commits in the master branch. In your case there won't be any so this is okay. For other people trying to do this where there are local commits, I don't think it's possible, since merge can only be run on the current branch.

Lekensteyn
  • 64,486
  • 22
  • 159
  • 192
Philip Beber
  • 1,115
  • 12
  • 18
  • Would this be equivalent to `git branch --force master origin/master`? This forces the local head `master` to point to the head of `origin`s `master` – Keego Apr 14 '17 at 01:06
4

git fetch origin master:master

  • "Pulls" (actually fetches) master.
  • If you have changes on your master that aren't pushed yet, origin/master is merged into your master.
  • If there are merge conflicts, you'll have to solve them first.
Luzian
  • 776
  • 1
  • 7
  • 10
3

You've got a worktree you don't want to touch, so use another one. Clone is cheap, it's built for this.

git fetch origin master       # nice linear tree
git clone . ../wip -b master  # wip's `origin/master` is my `master`
cd ../wip                     # .
git pull origin origin/master # merge origin's origin/master
git push origin master        # job's done, turn it in.
cd ../main
rm -rf ../wip                 # wip was pushed here, wip's done

git checkout master           # payload

The problem with all the other answers here is, they don't actually do the pull. If you need the merge or rebase you've got pull set up for, you need another worktree and the above procedure. Otherwise just git fetch; git checkout -B master origin/master will do.

jthill
  • 55,082
  • 5
  • 77
  • 137
  • 2
    When you run `git checkout master` you'll checkout the old `master` branch because you haven't done a `git pull` in the `main` folder to synchronise it with origin/master. This is what I am trying to avoid. – Malvineous Sep 25 '13 at 05:41
  • The checkout done by the clone is of the old master, but that checkout is into a directory the webserver's not looking at. The master checkout at the end is of the fully merged master that was pushed back from wip. – jthill Sep 25 '13 at 07:48
  • On line 6 you push the merged (updated) `master` back to `origin`, but I don't believe your final checkout is of this updated `master`. There is no `git pull` to update the `master` branch in the `main` directory, so unless I am missing something your commands are no different from just running `git checkout master` on its own and getting the old `master` tree. If you look closely, you are not running any commands in the `main` directory that communicate upstream (apart from line 1, which is run before you made any changes to the upstream repo.) – Malvineous Sep 26 '13 at 01:43
  • well, you could try it on a test repo, or check the push docs. – jthill Sep 26 '13 at 03:15
  • Well when I try it at line 5 I get the error `fatal: 'origin/wip' does not appear to be a git repository` but I realise my misunderstanding. When you push to `origin` you're pushing to the repository *in* `main` - I was thinking you were pushing to main's origin instead, forgetting that `git clone` is not an identical copy, the upstream branches are different. So I see what you are doing is instead of pulling into the target branch, you are pushing into it from outside. – Malvineous Sep 26 '13 at 08:34
  • That's right, and I should have said at the time both sorry for the error in my script and thanks for the correction and staying with it. – jthill Oct 02 '13 at 17:29
  • 1
    @jwg compared to what, please? Do be sure to address all OP's stated needs. – jthill Oct 17 '14 at 22:55
  • @jwg I second jthill comment. What are the alternatives. Your comment as it stands it's not constructive. – lucid_dreamer Jun 30 '17 at 22:40
2

Malvineous's solution work for me

$ git fetch                           # Update without changing any files
$ git branch -d master                # Remove out-of-date 'master' branch
$ git checkout --track origin/master  # Create and check out up-to-date 'master' branch

Just in give the error


warning: not deleting branch 'master' that is not yet merged to
         'refs/remotes/origin/master', even though it is merged to HEAD.
error: The branch 'master' is not fully merged.
If you are sure you want to delete it, run 'git branch -D master'.

So i run with -D option

thanks