dvcs branching (with mercurial)

Post on 10-May-2015

1.103 Views

Category:

Technology

4 Downloads

Preview:

Click to see full reader

TRANSCRIPT

DVCS branchingwith Mercurial

really

What is a branch?

In it's purest non-VCS specific definitiona line of 1+ changes that diverges from another one

1 2 3 4 5 6

1 2 3 4 6 7

5 8 9

I'm a branch!

or why you don't want to be forced into a linear history

Why branch?

Commit racesare a thing of every day with linear history

1 2 3 4

5

6

Hey!, my changes

had to go first!

Deal with it!

(and by "it" I mean merge conflicts)

to merge more

Why branch even some more?

Merging hellBranching is good, until you forget to merge early. Branch way more and you

will be merging more frequently and with less bad consequences.

1 2 3 4 126

5 94 ?

Uh, oh!... long-lived branches

or why merging has to kick-ass by design

Why are branches important to DVCSs?

Saved a new change?congratulations... you also created a new branch (one per clone)

Blessed Repository

ClonesClone A

Clone B

Clone C

1 2 3

3 4 5

3 4 5 6

3 4

T I M E

cloning happens three times at revision 3

Now how do I get my work back to the main repository?well, you merge

1 2 3 A:4 A:5

B:4 B:5 B:6

T I M E B:7*

C:4 C:5*

New commit after merging

Blessed Repository

merge

merge

branch

branch

First one to push back will not create a branch

And if I don't want to merge?...you don't, but you create heads

1 2 3 A:4 A:5

B:4 B:5 B:6

T I M E

C:4

Heads

Blessed Repository

Everything being worked at the default branch

(can be considered as a "trunk")

If these are branches, how come they have no name, huh?

● These are called "anonymous branches"● They are created implicitly each time you clone

○ When repositories are formally disconnected○ ...and as a consequence two new revisions can have the same parent○ Normally one exists per developer (as they work)

● You don't have to care about them○ They are frequently merged:

■ Each time you push, Mercurial notifies you should pull and merge

■ You can regularly pull and merge locally to keep your work in sync

○ Numbering is relative (sha1 hashes are tracked by Mercurial)● They give you breathing room to work

○ Without having to worry about creating named branches○ If you are already working in a named branch

cloning, named, anonymous, bookmarks

Types of branching

(aka the lazy/incorrect way to branch)

Clone to branch

Using clonesNot really recommended as real branching, but is easy to cleanup

Local Repository Clones for experimentingClone A

Clone B

Clone C

1 2 3

3 4 5

3 4 5 6

3 4

Cloning to branch

● Not remotely recommended as it can be just as convenient as working with any other branching method○ But folks still do it○ No need to know about branching concepts○ No need to clone from the remote repository, or even locally, just copy

& paste the repository folder○ Integrating work back to your main clone involves the same

● Use cases (or why people do it)○ Informal throw-away experimentation○ Working with two branches at the same time (without wanting to wait

for the 2-3 second update)● Understand it, but preferably don't do it

Pretty much what you expect

Named branches

How do you create one?name it, then commit it

1 2 4

5

DEFAULT

hg commit

hg update defaulthg branch my_branch

2

31

MY_BRANCH

hg update my_branch4

Executing hg branches should list "default" and "my_branch"

Executing hg branch should display the current branch as "my_branch" after 4

How do you merge them?Easy as 1-2-3

1 2 4

5

DEFAULT

MY_BRANCH 6

Do an hg update <branch or revision> to move the branch you want to merge another to.

Do an hg merge <branch or revision> to merge another branch into the current one.

hg update my_branch1hg merge default2

hg commit3

What do you do when you finish with it?just add the --close-branch option when you commit

1 2 4

5

DEFAULT

hg commit --close-branch1

MY_BRANCH 6 7

my_branch will no longer be listed in hg branches, but you

can reopen it by creating a new normal commit

Named branches

● Standard way of branching● Branches always get all pushed at the same time unless

specified● Recommendable to have a branch policy and/or naming

convention, e.g.:○ Types:

■ Bugfix branches should pull frequently from the baseline and be short-lived

■ Feature branches can be long-lived■ Hotfix branches should be merged before other branches

○ Naming

<type>-(<ticket system>_<ticket number>)?-<description>● Named branches are the only ones that use the "branch" command

works without cloning too

Anonymous branching

How do you create one?One step forward, one step backward, one step forward

1 2 3 4

5

DEFAULT

hg commithg update -r 3

hg commit

12

3

How do you create one?...ad nauseam

1 2 3 4

5

DEFAULT

hg commit

hg update -r 3

hg commit

1

2

36

7

8

hg commit6

hg update -r 55

hg commit4

hg update -r 37

hg commit8

Lots of heads in a single branchNot generally desirable, but can be easily be merged back

without affecting anyone

1 2 3 4

5

DEFAULT

6

7

8

heads

aside from a useful concept

What is a head?

The head revisionof a branch

1 2 3 4 5 6

1 2 3 4 6 7

5 8 9

head

one head

two heads

A branch within a branch...branch-ception

1 2 5 16 18 19

3 17 20

10 23

DEFAULT

RELEASE

FEATURE-X

BUGFIX-ISSUE_X

4 6 8 11 14 15

7 9 12 13 16

24 25 26

21 22

28

25

anonymous branches

within named branches

Looks crazybut it is not

Anonymous branching

● The branches that just happen by themselves.

● Can be made intentionally/forcefully by changing to a past revision and committing from it

● Anonymous branches can be counted by counting named branches and subtracting the number of heads

● Heads can be unmade easily (merge)● Not very sane to do anonymous branching

locally

The tags that follow you

Bookmarks

Making anonymous branching saneand they can be private (i.e. not pushed by default)

1 3 4

5

DEFAULT

hg commit

hg update -r 3

hg commit

1

2

3

hg bookmark my_stuff4

my_

stuf

f

And using them is as easy as with named branchesanonymous branches without having to track revision numbers

1 3 4

5

DEFAULT

hg update default5

hg update my_stuff6

my_

stuf

f

5

hg commit7

the "my_stuff"

bookmark moves

automatically when

you commit

...updating to a branch

...updating to a bookmark

Bookmarks

● A good local replacement for git's "private local branching"○ Can be deleted○ But keeping the history○ Can be shared (pushed/pulled) or not

● Bookmarks are not branches○ They just give a name to anonymous branches

TMYK

Other things you should know

No need to worry about them, 99% of the time, but you should understand what they

mean

Heads

Don't lose your heads...because there should be one head per branch (anonymous or named)

1 2 4

5

DEFAULT

MY_BRANCH

Executing hg heads should list 4 & 5 as heads

heads

Having 1+ heads in a named branch means there are pending mergesprobably someone used hg push -f, and you should go hit them on the head

(the one above their shoulders)

1 2 4

5

DEFAULT

MY_BRANCH

Executing hg heads should list 4, 6 & 7 as heads,

6 & 7 belonging to my_branch

heads

6

7

Having a merged head in a given branch means the branch is inactive...meaning it is abandoned, since it's changes are no longer unique to the

named branch (aka has no new code)

1 2 4

5

DEFAULT

MY_BRANCH

Executing hg branches should mark my_branch as "inactive"

Committing again on my_branch makes the branch active again

heads

6

inactive branch

The zen of branching

Feature branching

Feature branching

● Make a branch for each feature, refactor, experiment, bug, hotfix, etc.

● A fool-proof integration workflow○ While at your feature branch, keep pulling and

merging the common baseline into it as often as possible. Deal with merging often.

○ When finished with your feature branch:■ Merge baseline int it one last time■ Test/hack ad-nauseam■ Close branch■ Change to baseline and merge your branch into it

● How is this different in DVCS?: ○ It is a lot less scary because you can screw up

merges and nobody will be affected

Feature branching

● Benefits:○ Code-review is easy, even if you decided to do many

commits○ All your changes are "pull-request" ready in such a

way that is easier to think about (and even document)

○ You can multi-task and use branches to stashaway your changes

○ Collaboration with peers is simplified● You and branches are now BFFs ♥

You will wonder where branches were all this time and how could you live without them (oh... yeah, copy/pasting your project directory)

... I want private local branching like in Git

What about "private local branching"?

Mercurial's bookmarks == Git's branchesBecause both behave like pointers, they are private by

default and can be deleted without any trouble.

Mercurial repository cloned from source Git repository through hg-git

Git repository displaying all branches

Set phases to secret!Mercurial phases help you to go into "private mode" since in Mercurial's

philosophy everything is public by default. In Git, things are private by default.

1 2 3

4

DEFAULT

MY_BRANCH 5

6

public

draft

7

secret

MY_SECRET_BRANCH

hg commit

hg phase --secret --force

1

2

Next commits are secret, so they

are not shared by default,

therefore you can safely run

destructive operations on such a

branch

hg commit3

Set phases to secret!Secret changes are private, so nobody cares what you do to them. Make the first commit in a branch secret and the branch will be secret from there on.

1 2 3

4

DEFAULT

MY_BRANCH 5

6

public

draft

7

secret

MY_SECRET_BRANCH

hg push1

Push won't share your

branch at this point!

Set phases to secret!Finished with your branch and are confident about sharing it?, make the latest commit in the branch (i.e. the head) public and the phase will back-propagate

1 2 3

4

DEFAULT

MY_BRANCH 5

6

public

draft

7

secret

MY_SECRET_BRANCH

hg pushhg phase --draft

13Liked your branch?, good! =D,

make it public, then push

hg update -r 72

Push won't share your

branch at this point! hg push4

Push shares your

branch now!

Set phases to secret!If your experiment didn't work or you just want to delete your branch, just do it. If it is secret from the start you never pushed it, so don't worry about stripping

1 2 3

4

DEFAULT

MY_BRANCH 5

6

public

draft

7

secret

MY_SECRET_BRANCH

hg push1

Didn't like your branch?, just

leave it like that or delete it

hg strip -r 62

Push won't share your

branch at this point!

that was not hard

Conclusions

Conclusions

● Everybody branches and merges even without knowing it○ With anonymous branches○ Merging is very frequent○ ...and this information is taken into account for dealing with

conflicts● Creating & merging branches does not affect others

○ This takes out the fear factor○ Integration can happen away from the blessed repo, at several levels

● Branching becomes fun when experimenting locally● Developers can do the integrator's work at a lower level

top related