🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

Please help with a merge problem.

Started by
21 comments, last by Alberth 4 years, 3 months ago

I'm doing well making, “Mari Bro.” When I use Visual Studio and I have finished a feature I commit and push the new feature. After this I have made it a habit to merge that branch into the master. This works as expected, great! But, when I try to do all this with the console:

$ git checkout <branch> 
$ git add .
$ git commit -m <“my message”>
$ git push
$ git merge master
----------------Conflicts generated here!------------
$ git checkout master
$ git checkout -b <new_branch>

I get many conflicts in the files (around 30-40.) How do I get the files that are having errors to work perfectly like the Visual studio's GUI merge.

Thank you! Josheir

Advertisement

Hi Josheir,

This is because you got the merge logic the wrong way - git merges the specified branch into the currently checked out one. That means that you are trying to merge master into your new feature branch, which generates conflicts for the old files conflicting with the new ones!

So what you should do is insteas

git checkout master
git merge <branch>

Hope this helps!

Well, I tried all sorts of additional ways to solve this problem, but in the end I needed to get in manually and fix some conflicts. I probably solved seven or eight of them. Before, I did them by hand there was the following (please excuse my crudeness.)

<filename> source/diff

<filename> target/diff

When source or target was selected, two new files would be displayed. I selected source, target, target, and everything looks like it is working right. What is all that, anyways?

Thanx,

Josheir

You could also try rebasing master on top of your feature branch (it applies commits in a slightly different way, leaving you with fewer merge issues and a cleaner log):

git checkout master
git rebase <branch>

This may cause some other issues, though, but it shouldn't be a problem if you're the only one working on the master branch.
What I normally do is this:

git checkout <branch>
git rebase master
git checkout master
git merge <branch>

This way, you've already aligned the commits done on the master branch with your own, and the merge will often be painless.

It looks like this:

filename1 source diff

filename2 target diff

Source, target, and diff are hyperlinks.

The problem with git is there are too many things that can go wrong in an arbitrary setup that nobody can see or play with. For example, your first post starts with “checkout branch”, but that won't be possible without creating it first, and perhaps between branch creation and the checkout you are showing, things could be broken already.

I'd suggest you should try to make a reproducable very small example that breaks. Plain git at the command line is likely best, as that is common ground for everybody and can be run as a batch script.

As an example I made one, except this one works.

mkdir newdir
cd newdir

# Create repo, make initial version"
git init

echo "---------------- initial commit"
echo "x" > file1.txt
git add file1.txt
git ci -m "initial commit"

echo "--------------- make feature in a branch"
git branch feature
git checkout feature
echo "y" >> file1.txt
git add file1.txt
git ci -m "new feature"

echo "--------------- merge"
git checkout master
git merge feature

Output:

Initialized empty Git repository in ~/newdir/.git/
---------------- initial commit
[master (root-commit) 9669eb7] initial commit
 1 file changed, 1 insertion(+)
 create mode 100644 file1.txt
--------------- make feature in a branch
Switched to branch 'feature'
[feature 875c98a] new feature
 1 file changed, 1 insertion(+)
--------------- merge
Switched to branch 'master'
Updating 9669eb7..875c98a
Fast-forward
 file1.txt | 1 +
 1 file changed, 1 insertion(+)

Now everybody can copy/paste that script, run it, verify what you're saying, and change the script to fix whatever needs fixing.

Obviously, actual file contents isn't relevant, you only need to make changes to have git pick up a new file version.

I thought I should know a bit about git from the command line. Alberth, you mentioned that git can 'be broken.' When this happens, can a user start over with git, or is a wrong command not always salvageable?

Josheir

In my experience, it's salvageable, unless you destroy information, but plain git doesn't do that unless you tell it explicitly to do such a thing. It also may destroy information on successful completion of a command, eg ‘git rebase’, but such commands are designed to rewrite history, so it's desired to happen if you use them.

Unfortunately, being salvageable doesn't mean it's easy to understand how to achieve that. You can do pretty much anything you want, but with the above safeties on, it won't let you easily clean up the mess, since “mess” is also information that you cannot destroy without being explicit that you want it.

The key into git is to understand how it treats commit trees and branch labels, and what each command does to the tree. That allows you the usual checkout, branch, merge, rebase, commit commands. There is also reflog, but I never wandered into that area yet.

On a more practical point, add something like the following aliases to your config file:

[alias]
  lg = log -20 --graph --pretty=oneline --abbrev-commit --decorate --date=relative
  st = status -sb
  br = branch -v

‘git log’ is rather useless in its raw form at the command line, the above ‘git lg’ gives you a more readable 20 lines of log history in your current branch. ‘git status’ is really your friend while staging, rebasing, and resolving conflicts, but it tends to be a bit verbose, the above ‘git st’ makes it much more compact for the simple staging case. ‘git branch’ lists the branch, I found it useful to also have the commit log of the associated commit listed with ‘git br’. Likely you will find and add other useful aliases in time. (All git commands tend to have loads of options to tweak their behavior.)

For experimenting with commands, it can be useful to clone your repository locally at the disk first, ie “git clone path/to/existing/repo path/to/new/dir” (git is a distributed VCS, you can make copies of all repositories, including the ones you already have!). That way you can mess around as much as you like, and simply delete the cloned copy if you totally break it. Note that such a cloned copy is a proper git repo, its origin points back to ‘path/to/existing/repo’.

Finally, the ‘git reset’ command is the fastest way to move branch labels to any commit. It's the drop-big-bomb-on-it approach of git. and as such a potentially dangerous command. It may destroy entire branches (any commit that is not directly or indirectly attached to a branch label will eventually be deleted by git). In time, you'll find you won't need “git reset” much.

Alberth said:
Note that such a cloned copy is a proper git repo, its origin points back to ‘path/to/existing/repo’.

Well, I understand that cloning will allow me to make mistakes, but if the cloned copy has an origin of the original repo, than won't this cause problems because it will change this repo? For example when I push master to origin? Thanks again.

This topic is closed to new replies.

Advertisement