Hy,
1 .What are the most common scenarios where can happen merge conflicts in git between branches?
2 How to know when they are going to happen?
If I have a master branch and other evolution branch, if I have modified one file in the evolution branch and this file exists in master branch, when merging from evolution to master, how git determine merge conflicts or not between files in different branches? I mean, its easy for git to determine when there are conflicts when changes(from two different developers) point to the same file physically speaking but merge between branches we are talking about different files physically speaking, files in one branch and others in other branch.
Thanks
1) When since you made your evolution branch you have edited the same line of code in both branches.
For example say you branch evolution from master and you have main.py and a week later you edit line 253. Two days after that someone edits line 253 in main.py on the evolution branch. Now when you try to merge evolution into master you'll get a merge conflict. The best way to prevent this is communication. Who is working on what, what you should change and what you shouldn't.
2) You never really know until they happen. You can do a "dry run" merge just to see if there are any conflicts using git merge --no-commit --no-ff $BRANCH. As I said above, the best way to avoid them is communication between individuals.
3) All files that you have tracked in evolution will be merged into master. Even if these files don't yet exist in master. If they have the same name but are completely different (and you've edited the file in master since you've branched) that's a merge conflict.
Related
I was working locally on master branch. (by mistake) but it's ok with me this time as I control my code.
I took the following steps:
Egit->commit and push (to master)
Egit -> pull (to get other developers changes)
I got a message that there is a conflict with one file and I merged it.
Now I see: [My Product | Merged Master (up arrow)2 (down arrow)1]
I see in the symbols next to the files that the other developers created - black sign as if there are uncommitted.
A. What does the 2 up arrow and 1 down arrow mean?
B. Why do I see uncommitted changes? they are not mine
C. How can I work out on master after my merge?
D. I looked in bitbucket and didn't see that my changes were committed to the remote branch. What is wrong?
I know that I am supposed to work on branches - but for now - how do I fix the situation?
A. Two arrows up means you have two commits in your local branch that aren't in the remove branch. The one arrow down means there is one commit in the remote branch that you don't have locally. The solution is to do a git pull followed by a git push
B. Uncommitted changes are probably from your conflict. After a conflict, you have to resolve the conflict, add it to index and then commit that change. This is known as a merge commit. My guess is you have not done this.
C. Work out on master? You mean you want to work directly on top of master? After you resolve your conflict, you should be all set to do that. Branching is better though. To create your own branch just do git checkout -b my_featue_branch
The situation:
Several branches I constantly have to merge between them. Each branch has a special file that identifies the branch (with certain settings for commit mails, plugin options and more, doesn't matter here).
The problem:
Whenever I merge one branch to the other and this special file has been changed it will obviously overwrite the merge target file. But I don't want this to happen. Those files must be version controlled in their branches as they are an essential part of it, but they should not be merged at all as they contain branch specific information.
The question:
Is it possible (and how) to exclude a specific file from a merge? I'd like a solution that doesn't requier me to specify this on each merge as a paramter, but if there's nothing else then I bite the bullet.
The only way to exclude a file from a merge is to revert it right after the merge, before you commit, for example:
cd /path/to/repo/trunk
bzr merge ../branchA
bzr revert file/to/exclude
bzr commit -m 'merged from branchA'
Later, when you merge again from branchA, the bzr revert step in the middle is only necessary if the file changed in branchA since the last merge. So if the file doesn't change very often, then "biting the bullet" might not be all that bad.
My current SubVersion workflow is like so:
The trunk is used to make small content changes and bug fixes to the main source code.
Branches are used for adding/editing enhancements and projects.
So, trunk changes are made, tested, committed and deployed pretty quickly. Whereas, enhancements and projects need additional user testing and approval.
At time, I have two branches that need testing and approval at the same time. I don't want to merge to the trunk and commit until the changes are fully tested and approved.
What I need to do is merge both branches to one working copy without any commits.
I am using Tortoise SVN, and when I try to merge the second branch, I get an error message:
Cannot merge into a working copy that has local modifications
Is there a way that I can do this without committing either merge?
You currently have the trunk and 2 branches A and B (which are both branches from the trunk). I suggest you create yet another branch called AB as follows:
Switch your working folder to the trunk, if not there already
Update the latest and make sure you have no local modifications. If you do, either commit them (to the trunk) or revert them as appropriate.
Do one last update of your working folder from the trunk. Note the revision number you have updated to (call it revision R).
In the repo, copy revision R of the trunk to a new branch called "AB" (Do not switch your working folder to AB yet)
Merge your working folder with A.
Switch your working folder to AB.
Commit your working folder (to AB) and update (from AB).
Switch your working folder to the trunk.
Merge your working folder with B.
Switch your working folder to AB.
Commit your working folder to AB.
Test, and commit any fixes to AB.
When it's working and you're ready to merge everything to the trunk, do a final commit (to AB), then update your working folder (from AB).
Switch your working folder to the trunk.
Merge your working folder with AB
Test and fix
When it's working, commit working folder to the trunk.
Go out for beers
We had a similar workflow at one point. The solution I finally landed on was to keep multiple local copies, basically one per branch. Got a bit dicey at times with shared databases but overall it was very successful.
you can checkout another copy of the branch you want to merge into at a different place on your local drive, merge into it and then commit it. Then delete the whole 2nd working copy and return to your current task.
But it does seem that you are trying to subvert your own working practices - unless you want to just merge 2 branches together to commit all the work simultaneously and delete the 2 old branches... but then, what's stopping you from committing to them and merging normally in such a case?
Every merge operation is done in your local sandbox. You do not have to be worried until you commit some junky code.
I don't know the whole deploy process you do but what you can do is:
switch to branch A
merge branch A with branch B
build the app, deploy and test it
If all works fine you can commit all changes (you are on branch A). Then you can switch to trunk and merge with branch A. After all conflicts are solved you can commit on trunk and that is all.
Eric, " I may want to only deploy one change at a time..." and "merge two branches to one working copy without committing" are incompatible requirements: or you'll test branch after branch or mix two branches in one big mix.
Version A Anyway - you can merge any node with any node inside repo-tree, not only somebranch with trunk. I.e., in common, #JoelFan workflow is good, but - require less actions
copy HEAD of trunk to AB
Merge AB with A
Commit mergeset, test etc...
Merge AB with B
Test merged results
Merge to trunk and delete temporary AB-branch
Version B is 2-URL merge. svn help merge, "2-URL Merge Example" part as start. You can merge 2 independent branches into third in one command merge BRANCHA[#N] BRANCHB[#M] [TRUNK_WCPATH]
I'm trying to do some work on a project called NS-3, but my problem isn't project specific so I thought I'd ask here as well as the relevant mailing list.
Basically, a copy of the then current project code was made, and a fresh repo made of that code. Work was done on both the 'forked' version and the trunk.
So cloned the forked source, cd in, and hg pull <latest-dev>, hg merge, and while it wasn't a perfect merge, the changes that were unmergable were all related to one library change, so easily fixed (in theory). Naturally this optimistic attempt failed to build.
Now I'm not entirely sure where to go from here, I'm new to DCVS so please; ideas directed towards a 5 year old!
How can I find out which changeset of the forked version was last merged against the dev-trunk since they're separate but related repos?
The Case Where You Started With a Copy Not a Clone:
If this is what happened:
Project Exists
Copy (not clone) of project is made
hg init is run in each separate copy, creating two unrelated repositories
work is done in both copies
Then to merge them you want to do this in the newest of the two unrelated repos:
hg update 0, which jumps the repository back to its earliest point -- the point where it last looked identical to the other
copy in the contents of the working directory from the other repository
hg commit, which creates a new head
hg merge, which merges the two heads and also provides a base revision, which helps the merge process.
The key is getting a base revision involved if possible. What DVCS systems bring to the table that CVS and SVN don't is that every merge is a 3-way merge between two heads and the most recent common ancestor. Faking that common ancestor by creating the new head off the last point the two repos looked the same (revision 0 in the copy) simulates a base revision.
The Case Where You Started With a Clone Not a Copy
This is the classic DVCS case and there shouldn't be much you need to do. Just go into one of the clones, hg pull from the other and fire off the hg merge. If the merge requires input you'll use hg resolve to provide it, and when you're done hg commit.
If at this point your code isn't building/running then you need to just start debugging. Use hg blame to see what was being done near the lines that won't compile and try to suss out what was being done and how to work on it.
The merge process is much easier the more frequently you do it. Pull in up-stream changes daily, not monthly.
You can turn on the GraphLog extension and use the hg log -G command to see the point at which the two lines of development diverged, but in the end merging is development, and you just need to approach a non-building merge like you would any other software defect.
I'm just starting out with bazaar, and I've found that the checkout feature is the most useful for the way I work - namely I can c/o from a "master copy", do some development and then commit my changes in the new directory. This then updates the "master copy".
But what if I'm working on (eg) two projects, changing different portions of code? Say:
~/master - master copy
bzr co master ./gui
bzr co master ./engine
So I'm doing gui-related stuff in the ./gui directory and under-the-hood stuff in ./engine. How should I commit my changes? If I commit gui first, then engine, I guess any conflicts will be flagged in engine?
Is there a way to merge gui and engine, and then do just one commit to the master copy?
To make things a little more complicated, how about if I do this:
bzr branch gui ./mouse
Now I perhaps I've been working on mouse, but also on gui. If I want to merge the code from gui AND mouse, and then commit to master, what is the best way to manage this? Or indeed, if I also:
bzr branch gui ./keyboard
If I've changed altered gui, keyboard and mouse, should I hierarchically merge - ie mouse+keyboard, then merge this with gui, then commit gui to master?
I hope it is clear what I'm trying to achieve! Thanks in advance for your time.
If you have two checkouts, any time you commit changes to one, you will first have to pull down any changes from the other one, potentially having to resolve conflicts at each step. This is generally a good idea, since it's easier to resolve conflicts over time and make sure your code doesn't diverge too much.
However, it sounds like you want to have separate developers working on "gui" and "engine", or you just want to save your conflict resolution till development on both branches has completed. In this case, you should probably create them as independent branches with "bzr branch". Each branch can use local commits and not worry about conflicts with each other. Then when it comes time to merge you can do it one of 3 ways, all of which get the same end result:
1. Merge one branch into the other, then push it up to master:
cd gui
bzr merge ../engine
# manually fix any conflicts
bzr commit
bzr push #back up to main
The downside to the above method is that your "gui" branch now has the "engine" changes in it. Which is fine if you're going to throw away both branches once they're pushed back into the mainline. But if you want to keep the branches longer, you can:
2. Merge into the mainline:
cd master
bzr merge ../gui
bzr commit
bzr merge ../engine
# manually fix conflicts
bzr commit
This has the upside that you still have "gui" and "engine" as separate branches, but you've had to commit one to master before you were sure that they would both work together. So you really probably want to:
3. Create a merge branch:
bzr branch ~/master gui-engine-merge
cd gui-engine-merge
bzr merge ../gui
bzr commit
bzr merge ../engine
# manually fix conflicts
bzr commit
bzr push ~/master
# since this branch was only for merging, you don't need it anymore:
cd ..
rm -r gui-engine-merge
Yes, bzr should prevent you from checking in changes from the engine repo if it detects conflicts. Normally, you first do "bzr up" just prior to check-in and then make sure your stuff plays nice with others.
As for the second part of your question, dealing with mouse/keyboard branches, this is how I would normally do it. Simply cd into the gui dir, and then do:
bzr merge ../mouse
After merging the changes, you can then commit from the gui directory and it will send the changeset to the "master" directory.
Note that I'm hardly a bzr expert, but this is the way I've been dealing with SVN repos.