"Push creates new remote heads" and my humble workflow (kind of dummy question)

Pierre-Yves David pierre-yves.david at ens-lyon.org
Mon Jul 20 15:11:56 UTC 2020



On 7/18/20 6:13 PM, Victor Sudakov wrote:
> Pierre-Yves David wrote:
>>>
>>>>>>
>>>>>> Before the merge, you had two heads. To get one head, you can merge
>>>>>> them.
>>>>>
>>>>> Where did I have the two heads physically? There was one head at home,
>>>>> and
>>>>> one head at work, that's true. But I never allowed to create two heads
>>>>> in the cloud.
>>>>
>>>> Suppose we start in a situation where you have only one head X in the home,
>>>> work and cloud repos.
>>>>
>>>> Then, in the work repo, you create A on X. A is now the single head in the
>>>> work repo. Before driving home, you forget to push.
>>>
>>> OK, I see.
>>>
>>>>
>>>> Then, in the home repo, you create B on X. B is now the single head in the
>>>> home repo. You push to the central repo, which then also has a single head
>>>> B.
>>>>
>>>> Then, in the work repo, you pull. Now you have two heads A and B in the
>>>> repo.
>>>
>>> If I "pull -u" in the work repo, will my working directory be updated to
>>> B? Probably it will, because i've pulled from the central repo, right?
>>> Is it a good idea to always run "pull -u"? (which I do).
>>>
>>>>
>>>>> I want to fix my workflow somehow so that only one head (in all the
>>>>> repos) exists at a time.
>>>>
>>>> In your case, as the only person working on the repo, you could avoid the
>>>> situation by always pulling before committing and always pushing before
>>>> switching machines.
>>>
>>> Can I enforce this discipline?
>>
>> You can make sure you alway pull before committing by adding a hook in your
>> config.
>>
>>
>> [hooks]
>> pre-commit=hg pull -u
>>
>> (hook provided without any testing, so migh need adjustment to work)
> 
> This way, my history will be full of merges, which is not desirable.

The point of this hook is to pull and update before you commit. So this 
is not creating merge.

>>>> If you have the rebase extension enabled, you can pass "--rebase" to "hg
>>>> pull", which will linearize the changesets after pulling.
>>>
>>> This sounds interesting. Can you please explain on the X,A,B example
>>> above, what "pull --rebase" will do?
>>>
>>> "rebase working directory to branch head" does not sound exactly clear.
>>> Which branch? I don't have branches, just accidentally create two heads
>>> from time to time.
>>
>> Has soon are you start having multiple heads, you have topological branches.
>>
>> In your case you have two heads B and C. each on they own "topological
>> branch"
>>
>>
>> A---B
>>   \
>>    \-C
>>
>> Lets says you committed "C" locally and pulled "B". (so you working copy is
>> on changeset of C).
>>
>> rebase will "recreate" C (as a new changeset, C') on top of B. So the result
>> will be:
>>
>> A---B---C'
> 
> Great, but
> 
> a) what will happen when I push this rearranged history back into the
> cloud repo?

Mercurial has a phase concept. By default, you will not be able to 
rebase content you have pulled (or already pushed). So you are not 
"pushing back" anything since you push the version without merge from 
the start.

> b) do I need to hint to rebase what it should rebase on what? How
> does it know that it should put C on top of B, and not vice versa? Does
> it just always put the working copy topological branch on top of the
> pulled branch?

If there are only one other head, hg rebase will pick that. Otherwise, 
you can use `hg rebase --dest DESTINATION-REV`. You can also have a look 
at `hg help rebase` in general.

-- 
Pierre-Yves David



More information about the Mercurial mailing list