We are using git and the merge workflow. We have lot of git newbies (including
me) who either have an SVN or CVS background, or no version control background
at all.
Here is a frequent issue we are running into. Many of the team members were
using TortoiseGit. Merge conflicts happened fairly often because of concurrent
changes - or since they did not pull
every day. One user would do a pull, have
a merge conflict, resolve the merge conflict, and then look at the list of files
to be committed back.
But then the file list shows a lot of files, though there were merge conflicts
involved in only a few files. While committing, he unchecked all the other files
changes that he was not involved in, committed the results and pushed the
commit.
Result: All the commits by other people that had been done between this user's
previous commit and this one were lost!
First, why does Git or TortoiseGit just show a list of files that the user has
nothing to do in the list? Second, what is the correct thing to do in this
scenario - any answer from a TortoiseGit perspective will be helpful.
I shall address your questions line by line:
First, why does Git or TortoiseGit just show a list of files that the user has
nothing to do in the list?
When you merge in file changes from another branch, those changes may of course
contain work from other people. That is why you see file changes that aren't
necessarily yours. They represent all the changes that you're trying to merge
in.
Second, what is the correct thing to do in this scenario - any answer from a
TortoiseGit perspective will be helpful.
By un-checking files while you're resolving merge conflicts, you're essentially
telling TortoiseGit that you don't actually want to merge/keep those file
changes. You're basically saying "I don't want these changes, just throw them
away". If that's not what you actually want to do, then don't un-check those
files that TortoiseGit has automatically staged to be committed for you, even if
you weren't originally responsible for the changes in those files.
Your original question is the wrong one. Your workflow is broken so you are getting lots of conflicts. You should fix that. In the case that you do get a merge conflict, the state of the tree is that incoming changes are automatically staged and changes that need manual intervention will be in the working environment. For each un-staged file, users need to resolve conflicts and stage the changes. Once everything is ready you can commit the entire change set. This will be a merge commit so it should not contain new functionality or logic. If you unstage a file during this time, you are essentially over-writing the incoming change with the version that is in your local copy.
As for the deeper problems in your workflow, it sounds like people are committing directly to master. This is your main problem. No one should be committing directly to your trunk. Instead, folks should start working in a fresh branch. Even if the change is for one file, a productive git workflow very much relies on branching. Once the work in the branch is complete, you can merge your branch into master, or merge master into your branch. You can also re-base your branch in order to avoid multiple merge commits, although I have found that to be unnecessary.
I work flow would look like this:
# git checkout master
# git pull
# git branch newbranch
.
.
Do work
.
# git merge master <!-- Optional to pull in changes from master -->
.
.
# git add <files>
# git commit
# git checkout master
# git merge newbranch