Let's consider following two Mercurial scenarios:
Scenario A:
I have linear history from rev 1 to rev 5, I create branch foobar and commit revisions 5-11 to it. Then I switch to master and commit rev 12 to master. I have two branches (master and foobar), with one head each. Nice.
Scenario B:
I have a linear history from revision 1 to rev 10 (only one branch - master). I'd like to put revisions 6-10 to a new branch and continue my master from 5 onward, effectively putting myself into scenario A. I see that mercurial does not support retroactive naming of branches, so there's no way for me to transition to scenario A, but I'm thinking about hack like this one:
I create a new branch (and name it foobar), and commit rev 11 to it
I switch to master and do hg update -5, and then commit rev 12 to master
Do I now have two branches with one head each? If I understand correctly, the only difference between scenario A and scenario B is that in scenario B revs 5-10 are not labeled with "branch foobar", which in practice doesn't mean much, and all future behavior for scenario A and scenario B is equal. Am I right?
You are correct. When you do a hg update the earlier revision you will see the files as they were at that point and be able to isolate the differences from the revisions that you wanted on a branch.
Related
I found many ways to compare two commits/branches/tags, but I can't find a way to compare all commits in branch.
Suppose we have only branch master with 4 commits
example
We can easily compare all commits except first one in that or
that way
But none of these include changes from 'empty repository' state.
How could I do that?
On my local repository, I created a branch A from branch B. I did some work on branch A, and pushed A to github.
Then I created a pull request on github, in order to merge branch A into branch B, I heard that it is said to be "branch A is pulled from branch B". Is it correct?
Doesn't a pull request mean merging branch A into branch B?
What does "pulling" branch A from branch B mean?
It seems to me that the two meanings of a pull request are contrary to each other.
If you merge A into B it will be:
Branch A is pulled into B.
or
Branch B is pulled from A.
It refers to the branch you're currently at. If you're in branch B and pull from A, that pull will first fetch A and then merge A.
Pull and Merge are two different process.
"branch A pull from branch B" means you make a editable copy, call it A, from B (If A originally not exist).
"Merge A into B" means you are applying all the changes you made in A back into B
the reason people saying that "branch A is pulled from branch B" is because if A is not pull from B, it can not be merged back to B
There are two different uses of 'pull' in git terminology and, while not contradictory, they can be confusing at first.
1. Pull:
From the command-line command git pull (also known as a combination of fetch and merge). Essentially just gets the remote code (or 'pulls' it to your computer) and merges it into your local code. Read more here.
2. Pull request:
When you want to merge your changes into the repo. Generally opens a discussion and review of your changes before the pull request (or 'PR') is accepted. Read more here.
As an aside, there is also a 'push' command, which may make things clearer (and reiterate the direction pushing and pulling to and from local and remote repos). git push 'pushes' your commits from local to remote (i.e. the opposite of #1, git pull). Read more here.
I have a branch named A. I create another branch from A named as B. I work on the new branch B and push it. Later on I work on branch A and push it. Now, I switch back to branch B but I want it to update with the latest changes of branch A.
so should I merge from branch A to branch B, or branch B to branch A
In a normal case, the result of the merge is usually unique, whether you go to one direction or the other. The branch destination, however, depends only on your interpretation of the branches.
For example, you should merge the development branches in the stable branch only when they are deemed ready, but the stable can go in development more often.
I have a theoretical question about possible VCS merging.
I know that many VCS use 3 revision merge, which is common ancestor, "mine" and "your" revision. I know how they works.
I've thought about another alternative, recursive revision merge, haven't found this in Google.
"You found America!" you might think. I know Git use recursive merge.
But the reason Git is using recursive merge is for criss-cross merge
I'm talking about a normal case, non criss-cross merge.
For example, we have a common ancestor, A, and to branches, 1 and 2.
branch 1: B, C, D, E, F, G
branch 2: B', C', D', E', F', G'
As said before, A is the common ancestor so it's the parent of B and B'.
We want to merge G and G' into branch 1. The common way that Git and Mercurial use is the diff3:
diff3(ancestor = A, mine = G, yours = G')
This will compute merge by computing 3 version only, which is O(1).
The alternative algorithm I thought about is O(n):
merge the closest revisions to ancestor first.
merge the result with the next closest revision from branch 1
merge the result with the next closest revision from branch 2 (if remain)
repeat (in loop) to step 2 if there any revision in branch 1 remain.
In the above example it looks like:
merge B and B'
merge the result with C
merge the result with C'
merge the result with D
and so on...
The question I couldn't resolve is - Is there any case that my way is safer and more accurate (in non criss-cross merge) than the traditional 3 revision merge?
Can my way avoid conflicts that the traditional way cause?
Can my way create new conflicts that the tradition way doesn't cause?
Does my way conflicts are not "real" conflicts? (which the tradition way doesn't cause)
We want to merge G and G' into branch 1.
Why we want merge G into branch1? G is already in branch1. In best case we give nothing from this merge, in worst - conflict. Same for all other revisions without '
So only B' - G' need to be merged to branch1. And this is the 3-way merge.
BTW. third component of 3-way merge not 'common ancestor', but 'base'. Common ancestor can be base but not always.
In CVS I have a branch (b) off another branch (a) which is off the trunk/head.
Some bug fixes were made in branch (a) that I'd like to go ahead and use in branch (b). How can I pull those fixes into my branch in Eclipse?
head
|
v
a (with bug fixes)
|
v
b (needs bug fixes)
Ideally what you need is to have two tags on a for every feature you want to merge, and then merge the difference between those two tags into b. However, you would also need to remember which ones you have already merged, because CVS doesn't remember that.
When I was working in a company that used CVS and branches, our policy was that bugfixes from branches (a in this case) that ought to be used by other branches need to get merged into the trunk first, and all the other branches merge them from there.
However, it was still very painful if you wanted to cherry-pick individual bugfixes. Essentially, you'd have to remember every fix you've merged (by two tags, marking the beginning and the end of the changes making up that fix).
Generally, in CVS it's much better to remember (in a tag) up to which revision you have merged, and merge everything from there to the head (and then move the tag to the head). In CVS, cherry-picking is painful and requires you to store the merge history somewhere.