Question

I need a bit of advice on the merging my development branch to the master branch. Also note that I'm using Git Extensions so try to avoid too much command line jargon if possible.

Say I've made 3 commits on the dev branch (and I still currently have it checked out, and the mst branch has 1 commit after from when I branched off.

dev:    1 ---> 2 ---> 3
       /
      /
mst: 0 --- X

Now I want to merge my dev branch into the mst branch BUT, I actually only want to merge commits 1 & 2.

My understanding is that I'll need to CHECKOUT mst (stash or make a temp commit beforehand for any in-progress work) and merge mst with commit 2.

dev:    1 ---> 2 ---> 3
       /        \
      /          \
mst: 0 --- X ---- 4

Now, commit 3 is out of sync so the next thing to do is to re-sync the dev branch. To do this, I need to CHECKOUT dev and either merge dev with mst or rebase dev onto mst

ie.

dev:     1 ---> 2 ---> 3 --- 5
        /        \          /
       /          \   ------
      /            \ /
mst: 0 ---- X ----- 4

or

dev:    1 ---> 2     5
       /        \   /
      /          \ /
mst: 0 --- X ---- 4

The main issue that doesn't sit well with the other developers is that merging might become a huge time waster because

  1. you need to "save" your current work, then checkout mst then go back to checkout dev (we're using VB6, so we also need to close and reopen VB6 to reload the files because of potential merge conflicts and VB6 doesn't recognise files that have been modified externally)
  2. the double merge process (one to update mst and the other to re-sync dev)

Also, I've had some reliability issues with stash (sometimes stash pop prevents me from popping), which is why I suggest to my fellow developers to just make a temp commit (after commit 3), then do a mixed reset at the end.

We're a small company so getting things out as fast as possible is a priority (but we can't push out everything because some things be held back). Is this many steps actually required, or is there a faster way?

Was it helpful?

Solution

Git requires use of a working directory and index during a merge operation because you'll need them to resolve any merge conflicts that arise.

If you need to keep your working directory in a dirty state while you do the merge, then you can create a cloned repository using your primary local repository as the origin. Then do all your merging in your clone, and fetch the changes back into your primary repository

You can use Git Extensions to do the clone, or you can use a command such as:

cd C:\Users\Basewq\Code
git clone MyProject MyProjectForMerging

Then, when you wanted to do a merge without disrupting your working directory, pull changes from MyProject into MyProjectForMerging, do the merge, then fetch the commits back into MyProject (warning: don't push changes into MyProject, always fetch/pull). Again, you can use Git Extensions, or you can use the command line:

cd C:\Users\Basewq\Code\MyProjectForMerging
git checkout mst
git pull
git merge dev

And to bring the changes back in to your primary repository:

cd ..\MyProject
git fetch ..\MyProjectForMerging

Now the commits will be in the MyProject repository, ready to be pushed back to origin or wherever. You could also push from MyProjectForMerging into any other remotes, if you wanted.

OTHER TIPS

Use Branches

As suggested in the comments, the easiest way to do this is to create a new branch after the second commit (as in, just before you start working on the changes for commit #3).

If you do it like this, you will have a clean merge-point, no matter what further work you do.

Your workflow seems to be influenced by prior experience with centralized vcs. Just because there's a branch 'master' (mst) or 'develop' (dev) on your authorative repo doesn't mean you have to call them the same, or that there needs to be a one-to-one correspondence.

I feel that in git, it's often easier to create short-lived branches (with whatever name), and then simply merge the appropriate branches when pushing to your public or the authorative repo.

What is the tool you are using? I use Mac client for github:

http://mac.github.com/.

Branching, merging, changing between branches are just 30sec operations for me with this excellent tool. But of course you work on a quite a high abstraction level, but for day-today use thats is just what I need.

It has a windows varient too, but I haven't used and do not know if any limitation exists there:

http://windows.github.com/


Mainly there are 3 levels of source management tools:

1) VSS style blocked checkouts: This is the historical way of doing it.. If you have one developer or developers who do not work on same files simultaneously this could work for you.

2) SVN style non blocking checkouts: All developers work on a central repo, but they may work on the same file simultaneously. If there are conflicts, those need to be resolved before committing (update/resolve before commit)

3) Git style distributed SCM: This brings best value when you have developers who do own independent development with their local repos for longer periods of time. Once they are satisfied with the outcome, they may decide to publish their changes to the parent repo. Mostly used for open source development.

You need to pick the best model that work for your development style. For most of the commercial organizations with a closely working team, SVN model works quite good. If you have more complicated development team, Git may help you to deal with it.

Git requires use of a working directory and index during a merge operation because you'll need them to resolve any merge conflicts that arise.

If you need to keep your working directory in a dirty state while you do the merge, then you can tell Git to temporarily use an alternative working directory and index. However, this requires the command line and might be confusing.

The goal is to create a temporary index file and a temporary working directory. Point Git to them, do the merge, then restore the normal index and working directory.

:: Create a temporary working directory, but use my normal repository

mkdir C:\Temp\MyProject
set GIT_DIR=C:\Users\Basewq\Code\MyProject  -- (path to my normal repo)
set GIT_INDEX_FILE=C:\Temp\index
set GIT_WORK_TREE=C:\Temp\MyProject

:: Now do the merge in C:\Temp\MyProject

git checkout mst
git merge dev

:: Now put everything back

set GIT_DIR=
set GIT_INDEX_FILE=
set GIT_WORK_TREE=
del C:\Temp\index
rd /q /s C:\Temp\MyProject
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top