244

We recently switched from SVN to Git and at the same time put our live systems into version control (instead of local checkout and file copy to live).

On the project I'm assigned to we all access the same repository and to get changes into live we just git pull there. This causes problems because our web designers push changes into the VCS that should not be live yet but should be on the web-testing environment.

When one of the developers now pulls into live he gets all (possibly unfinished) changes.

I thought of switching live to an extra branch and just merge what changed but due to my lack of git knowledge I have no idea how.

My idea is:

  • Create a new branch in live (git branch live).
  • Every time something has to go live
    • Pull changes in master (like: git checkout master; git pull; git checkout live)
    • git merge master

The problem is that switching to master or pulling everything directly into the live system would cause problems so I'd prefer to avoid this.

Is there any way to do this or is there any better way to manage the live system (except for training the webbies to not push unfinished stuff)?

5
  • 2
    git pull --all will by default not pull master into live, it will pull master and merge it with master, and (if existing on the server) pull live to merge into live. Did you try it? Jul 16, 2010 at 7:56
  • Is your problem caused by a file that was not under version control before branching off live and git-added after modification to master later on? That's what happened to me before, usually it should suffice to temporarily rename that file, or if it isn't needed at live, use git checkout -f to ignore the problem - but make a backup! Jul 16, 2010 at 10:37
  • 2
  • I'm not sure how this is related to stackoverflow.com/questions/3216360/… - that said there is a clear workflow issue here, and I think an easy fix would be to use a Fork/PR flow for live and give devs the ability to test on their own fork. Only production-ready code gets approved and merged in the repo (you make sure approvers are aware and filtering properly) while devs can commit and test on their own forks (which are some sort of branches anyway). Make sure devs cannot push directly and must go through PR/review. Sep 16, 2020 at 7:15
  • 1
    @ThomasGuyot-Sionnest this question is 10 years old, 4 years older than e.g. Gitlab. Things were... different... back then
    – user27709
    Sep 16, 2020 at 7:29

5 Answers 5

394

I was able to pull changes from origin/master into master while working in another branch by using this command:

git fetch origin master:master

For a deeper dive into what's going on, check out the excellent answer to this Stack Overflow question. The main take-away for me was that this command only works for a fast-forward merge.

8
  • 12
    Awesome! Exactly what I was looking for - this needs to be much more prominently documented... Jan 14, 2019 at 9:22
  • 4
    You can find documentation on this here: git-scm.com/docs/git-fetch#_examples
    – c1moore
    Feb 8, 2019 at 14:16
  • 15
    fetch != pull
    – D. Kovács
    Jul 16, 2019 at 7:21
  • 9
    This does update the specified branch to the upstream branch. 👍
    – sean
    Jan 16, 2020 at 7:15
  • 10
    Add -f in case it's not a fast-forward, and you want to force update it: git fetch -f origin master:master
    – Diego
    Jan 30, 2020 at 11:37
21
+50

You can use git stash before checking out master and pulling, and after checking out live again use git stash pop (or if your git is older, git stash apply and git stash clear assuming you haven't stashed anything else)

7
  • 9
    git pull --all will fetch all remotes, but it will still try to merge a branch (or the default branch) into the current branch as well.
    – mipadi
    Jul 15, 2010 at 16:21
  • @mipadi yes, but only the current branch into itself whithout trying to checkout master and causing the conflict, no? Jul 16, 2010 at 6:13
  • It'll merge whatever branch is configured to be automatically merged into the current branch (if such a branch is configured).
    – mipadi
    Jul 16, 2010 at 6:26
  • 1
    @Superole It's documented as "fetch all remotes", which includes not only multiple repositories, but also branches. Though in hindsight, git fetch --all might have been a better answer Jul 25, 2013 at 9:02
  • 3
    @TobiasKienzler It only instructs git to fetch from all configured remotes. The most common case is to have only one remote named origin. IF you happen to have more than one remote with the same branch as your current, and they are not in a fast-forward relationship to eachother, THEN using the --all option will give you an octopus merge of the different versions of the branch into the current! So my advice is to stay away from --all unless that is what you're after, because in most other cases it will give you nothing.
    – Superole
    Jul 25, 2013 at 9:24
14

Solve the problem first. They should not be pushing to a branch they have no business pushing to.

What you seem to be asking would be something like

git checkout live
git pull origin master

This will attempt a merge of the remote master and your live branch.

2
  • The problem is that we currently have only one branch and it won't really be possible to change that since everyone is too used to SVN and not willing to learn the advantages of something new. It will only be possible to create a new branch in the live directory. Merging the remote master to the live branch is what i want to avoid as i cannot prevent anyone from pushing debug code, incomplete functions, syntax errors and anything else to the master (I'm just the junior developer after all). Thanks for your suggestion though.
    – user27709
    Jul 13, 2010 at 14:16
  • 2
    @dbeme: You could use tarballs and patches. ;) Unless they're willing to learn git (and it's not hard at all to branch and merge) you're going to have issues.
    – Josh K
    Jul 13, 2010 at 15:52
4

First off, note you never actually need a local copy of master if you aren't committing directly to it. So the simplest solution to your problem is to change this part of your workflow:

git merge master

to

git merge origin/master

Then you don't have to bother pulling down the local branch. That being said, if you prefer to have the local copy, it's conceptually easier to think of "updating master" without checking it out first, this way:

# delete your local master (normally either -d or -D should work here)
git branch -D master
# create a new copy of master from the remote copy
git branch master origin/master

And there's a faster way too, since you can force it and skip the delete:

# replace your local copy of master with it's remote version, even if it already exists
git branch -f master origin/master

Obviously, all of these commands assume you have already fetched from the latest origin beforehand. If not, perform git fetch first.

2
  • Doesn't this use a stored copy of the remote branch, not the actual remote branch? origin/master is technically a local branch that represents the remote branch, but that doesn't mean its up to date with actual remote. As I understand it. Oct 12, 2020 at 17:29
  • @KeithTyler correct. That's the reason for the last sentence. When you fetch you are updating your copy from the actual remote.
    – TTT
    Oct 12, 2020 at 17:38
1

I recommend that you create a testing git repo for everyone to commit. All repos, including your live website will be clones of the testing repo. In this manner, anyone can push to testing without touching the live web site. When someone needs to update the live site, then you can pull the live site from the git testing repo. This workflow is fairly similar to SVN. For extra flexibility, I recommend using the "live" branch that you describe.

To summarize, everyone's git repo is a clone of the testing repo. The live production site is just a clone of the testing repo as well. Alternatively, testing could be a clone of live prodcution so that a "git push" always moves toward production.

Other options including adding the "live" branch to this arrangement or including a "staging" repo between testing and production. For extra security, I recommend restricting access to the live git repo and forcing people to use a secured script that does the pull to live production.

You must log in to answer this question.