268

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 Answers5

425

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.

danba
  • 103
Jeff B
  • 4,997
22

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)

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.

Josh K
  • 12,990
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.

TTT
  • 735
  • 5
  • 13
2

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.

edgester
  • 182