2

We are a team of developers who switched from SVN to Git thinking it would be simpler and more standard. Unfortunately, until now we only encountered failures and problems.

We don't have the need for feature branches. We have a single branch called "develop" which all developers are sharing.

We are used to TortoiseSVN so we decided to go with TortoiseGit for the UI.

Commit and Push works great. Problem come with the Pull operation. SVN was great, even with local changes it downloaded the new version, auto-merged what's possible and ask to resolve conflicting files. Under Git, if you have local changes with the same files it just stop there (even if it could auto-merge). You have two choices, either commit your local changes (even if you work in halfway done) which pollute the "show log" windows with tons of useless commit, or stash, pull, pop stash which do something similar as SVN was doing just with some useless steps. Any better way?

The stash pop operation try to auto-merge (nice), but on a real conflict things go bad. Under SVN it was easy, you had the new file one side and the local file on the other side of a diff view and just fixed your local side and save it and mark as resolve. Under Git, you have fours files, the "normal" one, a BASE one, a REMOTE one and a LOCAL one. One completely mixed up thing is that the "remote" file (theirs) is actually the stashed file containing YOUR changes, so it's not helping for clarity.

So you select the "Edit conflicts" menu option which open the Merge Tool. The TortoiseGitMerge interface is not very friendly and the KDiff3 is widely used online so we decided to use it. So you press the Merge button which create a "merged" tab and on the lines with conflict you can press the A,B,C buttons. Until now, it's okay. Problem is, when you save this resulting file, it saves under file.cs.LOCAL.cs (instead of file.cs?). Then, under TortoiseGit, whether you select "Resolved", "Resolve using mine" or "Resolve using theirs", it just delete your merged files and give you the wrong version of the final file (without the merge work done). The only way we managed to get it is to make a temporary backup of the merged file, flag as resolved and recopy the backup. What the hell? Where in our work flow are we doing things wrong?

Dunge
  • 532
  • 3
  • 19
  • Sounds like you're using Git too much like SVN instead of Git, and not taking advantage of Git's ability to commit changes locally and rewrite local history before sharing those changes with other developers. Also, could you break up your last paragraph a little more please, it's a little too big to digest easily. –  Mar 13 '14 at 19:00
  • It doesn't make sense to pull (in new remote changes) in the middle of doing (local) changes, unless with `pull --rebase` (i.e., add my changes on top of the remote ones). Each developer *can* have as many local branches as they please, and only merge them into the master one for publishing. Perhaps look for suggestions on workflows that use git effectively, like the ones at [atlassian](https://www.atlassian.com/git/workflows). – vonbrand Mar 13 '14 at 19:09
  • Thanks Cupcake for the reply. You are talking about committing multiple time before pushing? We can do that and it work fine (even though I can't think of a reason why I would want to do that). As I mentioned, the problem is on Pull. I split my last paragraph as suggested. vonbrad : rebase seems interesting, except that logically you would want add remote changes on top of the local one, not the inverse. And why do you say it's not logical? I'm working on a feature, someone else update the rest of the application, I would like to see their changes active while still working on my feature. – Dunge Mar 13 '14 at 19:17
  • In agreement with @Cupcake - it seems you are trying to shoehorn `git` into a development model based on SVN. Many of these sorts of problems become non-issues if you use `git` the way it was designed to be used... In other words, yes, you do need feature branches, because they are the key thing that `git` brings to the table to avoid the above scenarios and issues... – twalberg Mar 13 '14 at 19:34
  • twalberg : You might be right, my question was always how would we go to use "git the way it was designed"? Aren't features branches used when you want to share work between multiple developers that aren't affected by other work done on the develop branch? In our case, the only thing we want is a simple way to always push/pull changes at any time on the same base and if possible without having to manually create/delete branches all the time. – Dunge Mar 13 '14 at 19:45
  • Feature branches are best used to separate the work of different individuals (or different features, bug-fixes, etc.) so that you don't run into the case where "person A made commit X on top of the master branch at commit L, and person B made commit Y on top of the master branch at commit L, and now we don't know which one is right" problem. If both X and Y are in separate branches that originated at L, merging them back together onto the master branch is much simpler. – twalberg Mar 13 '14 at 21:41

1 Answers1

2

I'll try to give some pointers and tips. First I'll just say this. It's little point in going to git if you just need the svn-features. svn is fine in those cases. git can do a lot of more powerful things but you'll have to do it the git-way, any other way is going to be cumbersome, at best.

That said. If your long term goal is to fully adopt git thinking it might help to "just do it" like it was svn for a while and gradually change your thinking.

When you do a git pull it actually does one of two things

git fetch
git merge

or

git fetch
git rebase

It depends on a config setting or the option --rebase. On a local branch (even local master) I prefer to do rebase but when it comes to conflicts "their" and "mine" is very confusing but here is what happens.

  1. git will first rewind your working copy and HEAD back to where your local branch and origins branch diverged
  2. then apply all of the commits from origin.
  3. git will then try to re-apply your commits one by one. If a conflict happens now it's going to call your change, then one being re-applied "theirs" which is correct but very confusing. Think of "mine" being what is already in the working copy and "theirs" as what's going to be added and it makes more sense.

When you do a merge instead of a rebase then it's the other way around. Your changes are already in the working copy, "mine", and the changes that are being merged in are "their". Unfortunately very confusing.

I've never used kdiff3 or TortoiseGIT so I can't help there but I'll say this, if you get a conflict using the command line tool the file with the original name is going to be full of conflict markers, just as it would with svn. Use whatever tool your comfortable with to solve the conflict and then

git add <conflict file>
git rebase --continue 

or

git add <conflict file>
git commit

depending on if you do rebase or merge to resolve the conflict and move on.

Andreas Wederbrand
  • 38,065
  • 11
  • 68
  • 78
  • That's helpful. Rebase seems like the typical solution because it won't to pollute the file log with tons of useless "merge" commits. I found the configuration line to add in .gitconfig. But of course I can't ask all the developers to use console commands so I hope TortoiseGit is fine with that. Now, it still don't explain why the merge tool is not functioning as supposed. – Dunge Mar 13 '14 at 20:25
  • Yeah TortoiseGit Pull command seems to ignore the config (use its own parameters) and the Rebase menu option ask to stash my changes before entering it.. so I'm still mixed up. – Dunge Mar 13 '14 at 21:08