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.
Related
I am using a named branch for a customer specific version. On this branch, I have some files that are customer-specific (Branding, logos,...). These files should never be merged to the default branch.
I want to make sure that these customer-specific files will never be merged in the default branch.
Is there a way to mark some files as branch specific in Mercurial?
No, not that I know of such feature. However, you can merge that branch once into default, taking care to merge into default only what you want to see merged (e.g. hg forget those customer files during the merge into default). In later merges those files you chose to forget in the default branch will be "only" show up with
remote changed customer which local deleted
use (c)hanged version, leave (d)eleted, or leave (u)nresolved? d
where you should choose 'd'. An example transcript of such exercise you can find in this paste
If those files are well-known and fairly stable, you could create a commit hook (client-side) and/or a pretxnchangegroup hook (server side) which checks those files not being present in any commit within the default branch, and which rejects the commit when any such file is committed to default.
You can use merge-patterns.
hg merge --config merge-patterns.somefile=internal:local otherbranch
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.
Me and my friend need to develop a project parallely. how to do this?
I created two branch worked on each leaf. Tried to merge the leaves but getting conflict error for edited file. What is the way to merge them?
I would like to know if it possible to have 2 leaves in a single branch? If so then how to create a new leaf in addition to the default leaf.
Each branch has one leaf at any time. These represent the most recent state of the repository from the perspective of each branch. As your post mentions, branches are used to afford parallel developments within the repository. They are also created automatically (called a "fork" in such a case) to prevent two commits to same branch when each commit has the same immediate ancestor... allowing this would be just like having multiple leaves on the same branch.
To create a new branch of development, one opens a fossil repo and executes a command like:
fossil branch new some_feature trunk
Complete example
For the sake of example, I quickly created a new repository and added a single file to the trunk (the only branch initially), file.txt. The initial contents of my example file are:
here
is
a
file
After committing the added file with the comment, "create baseline", I created a development branch for a new feature called "some_feature" based on the current state (aka the leaf) of the trunk branch...
fossil branch new some_feature trunk
Now there are two branches, trunk and some_feature. Creating the branch does not change my working branch, so I am still in trunk. Then I edited the baseline file to:
here
is
a
file
folder
...adding "folder" to the end. Then I committed the change to trunk with the comment, "modification on first branch... trunk. Then I switched development to the some_feature branch...
fossil co some_feature
From this second branch, I also edited the last line of the baseline file:
here
is
a
file
reader
...adding "reader" to the end. Then I committed the change to some_feature with the comment, "modification on second branch... some_feature".
To merge development, you chose the branch you want to merge changes into. In this case, I will merge the feature branch changes into the trunk. To do this you must first checkout the destination branch for the merge... in my case, trunk.
fossil co trunk
Then, I merge in the change from the specific commit of the other branch. In my case, I'll use the leaf of that branch:
fossil merge some_feature
MERGE file.txt
***** 1 merge conflicts in file.txt
WARNING: 1 merge conflicts
"fossil undo" is available to undo changes to the working checkout.
This leaves me with four files now in my working directory instead of one. No new commit/checkin has actually made it back to the repository proper. The four files are: file.txt, file.txt-baseline, file.txt-merge, and file.txt-original. "file.txt-baseline" is the file as it existed in the most recent common ancestor of the merging branches. "file.txt-original" is the file as it existed in the target brach, in my case, trunk, just before the merge. "file.txt-merge" is the file as it existed in the branch you were merging from, in my case, some_feature. Finally, "file.txt" contains the contents of the baseline file with conflicting changes from the original and merge files annotated so you can decide how to deal with the differing contents.
In my case the generated conflicts file, "file.txt" looked like this:
here
is
a
file
<<<<<<< BEGIN MERGE CONFLICT: local copy shown first <<<<<<<<<<<<<<<
folder
======= COMMON ANCESTOR content follows ============================
======= MERGED IN content follows ==================================
reader
>>>>>>> END MERGE CONFLICT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Until the merge conflict annotations are removed from the file, fossil will not let you commit (or it will at least warn against it). Otherwise, you would make a commit with message, such as, "merged some_feature into trunk".
For reference, here is the event history diagram as provided by fossil for this example:
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.
How do I get a patch from a commit in order to send it to another developer? And how do I best avoid a merge conflict with this patch when merging our trees at a later date?
If you know how please explain how to do this in your VCS of choice such as subversion, git, Mercurial, bzr or etc.
In git you can pipe the output of git-diff between two commits like this:
git diff fa1afe1 deadbeef > patch.diff
Send the patch.diff to the developer and let him git-apply it to his workspace like this:
git apply patch.diff
If the other developer already has the commits available in his repository he could always pipe it in himself without merging like this:
git apply < git diff fa1afe1 deadbeef
You can then add and commit the changes in the diff the usual way.
Now here comes the interesting part when you have to merge the patch back to the master branch (that is public). Consider the following revision tree where C* is the applied patch from C in the master branch:
A---B---C---D master, public/master
\
E---C*---F feature_foo
You can use git-rebase to update the topic branch (in this example named feature_foo) with it's upstream head. What that means is when you type in the following:
git rebase master feature_foo
Git will rearrange the revision tree like this and will also apply the patch itself:
A---B---C---D master, public/master
\
E*---F* feature_foo
Merging to the upstream branch will now be an easy fast-forward merge. Also check that the new commits E* and F* work as the previous E and F respectively.
You can do the same thing against another developer's branch using the same steps but instead of doing it on a public repo, you'll be fetching revisions from the developer's repository. This way you won't have to ask the other developer for a patch if it is already available from what he published at his repo.
Please note to never rebase a public branch because the command will rewrite git history which is something you don't want to do on branches that people depend on and will create a mess when merging to remote repositories. Also never forget to integrate often so others in your team can take part of your changes.
In SVN you can simply make your changes then before commiting, pipe the output of the svn diff to a file as such
svn diff > mypatch.diff
you can then revert your changes and apply the patch at a later date using
patch -p0 -i mypatch.diff
As always don't blindly apply patches to your code and always inspect them first.
You may also find that the patch will break your source code if the source files have changed significantly enough since the patch was taken.
You also can not guarantee that there will not be merge conflicts when you attempt to check in the code.
Bzr handles sending a "merge directive", meaning it sends the patch for you so that the other party can simply click "OK" to merge and there's less futzing around with patch/apply etc.
just:
$ bzr send -o mycode.patch
In Subversion there is no nice way of doing this. Yes, you can use svn diff + patch but this will only postpone your problems until you are going to merge and by then chances are that you've forgotten about it.
The way you would do it in Subversion would be to create a branch, do the commit on the branch and ask the recipient of the patch to switch to the branch. Then you can merge the branch back to trunk in the usual way.