Does this scenario work using mercurial?
so if you have a central rep
Central -> Bob clones. Bob makes changes.
Alice Clones off bob, alice makes changes
Bob makes further changes
Alice pushes to central.
Bob pushes to central
Short answer: yes
Long answer:
Bob:
hg clone ssh://central/repo bob_local
cd bob_local
... // changed something
hg ci -m "ta-dah"
Alice:
hg clone bob_local alice_local
cd alice_local
... // changed something
hg ci -m "ta-dah from Alice"
hg push ssh://central/repo
Bob:
hg push // at this step Bob have to get warning about changesets from Alice and
// have to pull before push
Yes.
Really that's the best answer I could give. Try it and see.
Related
I can't push using mercurial, it states I have to merge. If I do hg merge, will it merge my branch with the main trunk, I really want to avoid that.
I created and modified some files. I did hg add to add them all. I did some commits but it won't let me push them to my branch.
I posted my output of hg commands below:
C:\Users\kacalica\Desktop\Projects\hydroinformatics>hg incoming
comparing with https://stcalica#bitbucket.org/nickrsan/hydroinformatics
searching for changes
no changes found
C:\Users\kacalica\Desktop\Projects\hydroinformatics>hg status
M hydro\forms.py
? graph_test.py
? hydro\mlgraph\__init__.py
? hydro\mlgraph\test.py
? hydro\plugins\__init__.py.orig
? hydro\urls.py.orig
? hydro\views.py.orig
? public\Hydroinformatics\media\test.txt
? public\Hydroinformatics\media\test_EPALM1I.txt
? public\Hydroinformatics\media\test_OIWsXcC.txt
? public\Hydroinformatics\media\test_v5s6RmF.txt
C:\Users\kacalica\Desktop\Projects\hydroinformatics>hg add
adding graph_test.py
adding hydro\mlgraph\__init__.py
adding hydro\mlgraph\test.py
adding hydro\plugins\__init__.py.orig
adding hydro\urls.py.orig
adding hydro\views.py.orig
adding public\Hydroinformatics\media\test.txt
adding public\Hydroinformatics\media\test_EPALM1I.txt
adding public\Hydroinformatics\media\test_OIWsXcC.txt
adding public\Hydroinformatics\media\test_v5s6RmF.txt
C:\Users\kacalica\Desktop\Projects\hydroinformatics>hg push
pushing to https://stcalica#bitbucket.org/nickrsan/hydroinformatics
searching for changes
abort: push creates new remote head b54ae56acf07 on branch 'WITHOUTPLUGINSGRAPHS'!
(merge or see "hg help push" for details about pushing new heads)
C:\Users\kacalica\Desktop\Projects\hydroinformatics>hg commit -m "added files"
abort: last update was interrupted
(use 'hg update' to get a consistent checkout)
C:\Users\kacalica\Desktop\Projects\hydroinformatics>hg update
0 files updated, 0 files merged, 0 files removed, 0 files unresolved
C:\Users\kacalica\Desktop\Projects\hydroinformatics>hg branch
WITHOUTPLUGINSGRAPHS
C:\Users\kacalica\Desktop\Projects\hydroinformatics>hg status
M hydro\forms.py
A graph_test.py
A hydro\mlgraph\__init__.py
A hydro\mlgraph\test.py
A hydro\plugins\__init__.py.orig
A hydro\urls.py.orig
A hydro\views.py.orig
A public\Hydroinformatics\media\test.txt
A public\Hydroinformatics\media\test_EPALM1I.txt
A public\Hydroinformatics\media\test_OIWsXcC.txt
A public\Hydroinformatics\media\test_v5s6RmF.txt
C:\Users\kacalica\Desktop\Projects\hydroinformatics>hg summary
parent: 36:b54ae56acf07 tip
actually added template
branch: WITHOUTPLUGINSGRAPHS
commit: 1 modified, 10 added
update: 10 new changesets, 2 branch heads (merge)
C:\Users\kacalica\Desktop\Projects\hydroinformatics>
OK, first of all, let's sort out our terminology here. In Mercurial, a "head" is a changeset with no child changesets (https://www.mercurial-scm.org/wiki/Head). Let's say you're working in default branch. If you're being told that pushing would create new remote heads, it means there's a different head revision in default on the remote repository (the one you're pushing to). If you pushed, default would have two head revisions!
How does this happen? Well, it might be another developer did a push in the meantime, or you pushed from another repository/computer by mistake. You don't want to push a branch with multiple heads, otherwise you end up with some crazy hydra with loads of heads, none of which has all the code.
First you need to pull from the remote repository. Next, you need to run "hg merge" - if you're using Hg-Workbench or similar, you might not see the other head immediately, so scroll down and find it. If you have conflicts, now's the time to resolve them. Make sure you commit your merge, and then you should be able to push.
If you're on a verison of Mercurial that's not more than a couple year's old do: hg push --new-branch which the hg help push shows lets you push a new branch:
--new-branch allow pushing a new branch
That'll only be necessary the first time you push a new branch -- it's just there to make sure you don't accidentally push something you didn't mean to share.
In the picture below I found Mozilla's mercurial repository graph with a situation that I thought was not possible. They have two commits that have the same parent where one is a merge. I have wanted to do this, but cannot find an answer.
# merge pull request from foo polish text
|\
| o bug 1 - add text ...
|/
o merge pull request from bar bug 2
How did they get this to occur? Usually when you pull changes in that add onto the head, if you attempt to merge you get "nothing to merge".
One method for achieving this is to use Mercurials built-in "debug" commands. They're effectively commands you should never need to use unless you're, you know, debugging Mercurial. Using them could in theory destroy your repository, so work on a clone if you really need to.
$ hg help --debug
...
debugsetparents
manually set the parents of the current working directory
What this command does is allow us to, as you can see, manually set the parents of the working directory - using this we can fake a merge.
So, with this knowledge, and with a degree of caution, we can do:
$ hg log --graph
# 1[tip] Change by A.N.Other
|
o 0 Local Change
$ hg debugsetparents 0 1
$ hg log --graph
# 1[tip] Change by A.N.Other
|
# 0 Local Change
$ hg commit -m "Merged"
$ hg log --graph
# 2[tip] Merged
|\
| o 1 Change by A.N.Other
|/
o 0 Local Change
It's not something that I would normally advise, but it would allow you to illustrate that you're pulling in some changes from "another branch", when that branch is actually at the tip of your changes, which I guess is the aim.
Also, note shambulator's comment below - for this to include the changes in 1, you need to have that as your working directory when performing the debugsetparents, otherwise you'll lose those changes. Unless of course your plan is to discard those changes, in which case you should update to changeset 0, and then fake the merge.
If I have a repo that looks like this:
A--B--C--D
\
E--F--G
How can I specify revision E? I can do something like -r 'ancestors(D,G)' to get B, but I want a reasonable way to specify E.
Also, let me explain why I'm doing this in case there is a better workflow.
In the above picture, A--B--C is in a main repository. A--B--E--F--G is in my own private forked repository, and I need to merge F (and only F) into the main repo. To do this, I pull my private repo into main, then graft F (to create D), and then use the hg strip extension to remove E--F--G and then push back up to the main repo.
Currently I do this by opening a gui tool and looking at the picture of the branches and manually copy-pasting the revision E from that tool. I don't like to use GUI tools to actually manage the repo, so I just paste that revision into a terminal for hg strip. This is the only thing I still need to do in the gui tool and I'd rather not have to launch it each time I do this. What I want, is to figure out how to specify the revision and then make an alais that does hg strip on that revision
I think that min(descendants(max(ancestor(D,G))) and not ancestors(D)) will get what you want.
It finds the newest common ancestor of D and G (max(ancestor(D,G))), gets all of its descendants and then excludes the ancestors of D. Finally, it uses min() to get the oldest of that set which is E.
The max() isn't really required in your example but covers the chance that you could have merged the main branch into yours at some point. You could remove that to make the query shorter. You could also shorten it by using :: as a shortcut for ancestors() and descendants() and ! as a shortcut for not which gives a crazy looking min(ancestor(D,G)::) and !::D)
I really wouldn't just pass this revset to hg strip though. I'd make sure that it gives the revision that you want before stripping it.
I'd consider using the Mercurial Queues extension for this workflow. You'd basically keep E, F and G in a patch queue, unapply all of them, pull, update to C, apply F and discard E and G. This would be something like this:
> hg qpop all
> hg pull -u
> hg qpush --move F
> hg qdelete E
> hg qdelete G
Where F, E and G are the names of the patch files that you created using hg qnew. It seems like a nicer workflow to me and doesn't involve deleting commits using complicated revset queries.
I actually found a better solution to my workflow, since I'm working with remote repositories.
I have a remote1 that containts A--B--C and a remote2 that has A--B--E--F--G and I want to graft F onto remote1.
Here'es the workflow I came up with, starting in a local clone of remote1 (using outgoing to solve the root problem)
$ hg pull remote2
$ hg graft F
$ hg push -r tip
$ hg strip -r 'roots(outgoing())'
The Scenario is as follows:
I cloned a Repo locally and made some changes and then committed.
hg clone test
vim abc
hg commit
Say the above gives me revision 1
I send this revision for review.
I make some more changes and make another commit.
vim xyz
hg commit
This gives us another revision say revision 2
Again, I send this as a new revision for review
I make some more changes and have some uncommitted changes.
vim 123
I get a request to update revision 1 with some more changes as a priority task.
Questions::
Q1 Now how do i make changes to Revision 1 ?
Q2 How do i get the differential between revision 0 and revision 1 to update the 1st review i sent ?
There are not rebase here
'hg help update' for returning back to any previous changeset (hg up, edit, commit, merge)
Storing unfinished 123 - commit, or shelve, or mq-patch
We're currently working on the new version (version 2.0) of an application.
We have a customer running version 1.0 of the app who found a bug. We updated to the tagged changeset for version 1.0 and located and fixed the bug.
We committed the change which created a new head in our source tree.
The question is how best to merge this? Ideally I would want to merge it into the changeset that followed version 1.0. I don't want to merge it into the tip because the code where the bug was found doesn't actually exist anymore.
I realise I perhaps should have created a separate branch for "v1.0 bug fix".
Thanks,
Ben
When moving a change within a repository using merge it's all about the most recent common ancestor of the place you have the change and the place you want it. If before making this fix your repo looked like this:
[a]-[b]-[c]-[d]
with the 1.0 tagged changeset being [b] then you now have this:
[a]-[b]-[c]-[d]
\
-[e]
where the fix is in [e]. If that's the case then you just need to do this:
hg update d
hg merge e
hg commit
Then you'll have this:
[a]-[b]-[c]-[d]-[f]
\ /
-[e]-----
If on the other hand before making the changes your repo looked like this:
[a]-[b]-[c]-[d]
\
-[e]-[f]
where the 1.0 rag pointed to [f] then you now have this:
[a]-[b]-[c]-[d]
\
-[e]-[f]-[g]
with the fix in [g]. If you want to move the changeset [g] into [d] without bringing [e] and [f] along with it, there's no good way to do it. The not-so-good way available to you (called cherrypicking) is to use the hg export and hg import commands.
No workflow requires cherry picking, but avoiding it requires a little forethought. In that second case you would avoid it by making the fix not on the 1.0 series (as a child of [f]) but instead as a child of the most recent common ancestor of the two places you want that change. Since you want that change in both [d] and [f] you look for their most recent common ancestor and see it's [b] and make the change as a child of that using these commands:
hg update b
..edit..
hg commit
leaving you with this graph:
[a]-[b]-[c]-[d]
\
\--[g]
\
-[e]-[f]
this fix, [g] is a new head, and you can merge it into both [d] (2.0) and [f] (1.0) without any cherry picking at all. The commands for that would be:
hg update d
hg merge g
hg commit
hg update f
hg merge g
hg commit
and the resulting graph would be:
[a]-[b]-[c]-[d]--[h]
\ /
\--[g]----
\ \
-[e]-[f]-[i]
where [h] is your new 2.0 with the fix, and [i] is your new 1.0 with the fix.
Summary: you can always avoid cherry picking with forethought, but it's not the end of the world if you didn't
It sounds like you have this:
[a]-[b]-[v1]-[c]-[d]-[v2]
\
-[fix]
and want to get rid of the extra head without merging any of the changes in [fix].
Option #1
The following commands will simple mark the branch closed, and it won't count as an extra head and be hidden from hg heads and hg branches commands:
hg update fix
hg commit --close-branch -m "closed branch"
Option #2
The following commands will "dummy merge" the extra head, throwing away any changes.
hg update v2
hg --config ui.merge=internal:fail merge
hg revert --all --rev .
hg commit -m "dummy merge"
the --config ui.merge=internal:fail flag prevents a merge tool from trying to merge any conflicts, but doesn't prevent files added to the other head from appearing, since there would be no merge conflicts with a newly added file. The revert will simply update all the files back to the first parent's state. You'll end up with:
[a]-[b]-[v1]-[c]-[d]-[v2]-[merge]
\ /
-[fix]-----------
but the content of [merge] will be the same as [v2].
Option #3
Yet another way to do a dummy merge:
hg update v2
hg debugsetparents v2 fix
hg commit -m "dummy merge"
This sets the working directory to v2, but then "fakes out" Mercurial that both v2 and fix are the parents and commits it as a merge.