~jan0sch/darcs-book
~jan0sch/darcs-book/en/09-tag-youre-it.md
~jan0sch/darcs-book/en/09-tag-youre-it.md
title: tag! You're it! next: index prev: chapter08 toclink: yes ---
tag
! You're it!We now have all the tools the we need to craft our patches and their
dependencies into a shape that we find satisfying. We know how to record
patches, pull
and push
work between other repositories, state dependencies
between patches, amend
them or just throw them away. But how do we indicate
that we have reached a point in our development where we have confidence in our
work and say: "Yes! We have finally reached one of our goals!"
As your project progresses you might pass a milestone every now and then. Once
you have decided that your current repository state meets all the conditions you
would like it to meet for such a milestone to occur it is useful to be able to
refer to that repository state by something like a version number (e.g '1.0') or
a code name. In darcs
we do this by creating a tag
. You can call your tag
any way you like but it's a good idea to stick to a certain naming scheme once
you start applying tags to your repository.
So let's take a look at darcs tag
which allows you to create a tag
.
To illustrate how tags work let's build ourselves are relatively simple example
repository and tag
it for fun and profit.
$ touch A B
$ darcs add A
Adding 'A'
$ darcs record -m A -a
Finished recording patch 'A'
$ darcs record -m B -a -l
Finished recording patch 'B'
$ darcs log
patch 4dd3f2b240fcae41674f6742213c0ac953981aa7
Author: raichoo@example.com
Date: Wed Jul 11 19:15:28 CEST 2018
* B
patch 773190b27402bae8af4895db5810010650652185
Author: raichoo@example.com
Date: Wed Jul 11 19:14:46 CEST 2018
* A
If we look at the dependency graph for this repository we will see that it is remarkably unspectacular. We just have two patches and they do not depend on each other in any way.
So if we were to capture the current state of this repository we need to ensure
that we pull in those two patches. To do this let's create a tag
we call it
1.0
so we can take a closer look at what darcs
is going to do.
$ darcs tag -m 1.0
Finished tagging patch 'TAG 1.0'
$ darcs log -v --last 1
patch 46094731f678f0741907b99b3bedeaff5febd27d
Author: raichoo@example.com
Date: Wed Jul 11 19:18:29 CEST 2018
tagged 1.0
depend patch 4dd3f2b240fcae41674f6742213c0ac953981aa7
* B
depend patch 773190b27402bae8af4895db5810010650652185
* A
As you can see tags are very much like patches. They have an author, a creation date as well as a hash, but instead of recording any changes they only depend on patches. This one obviously depends on the two patches we have previously recorded to capture the repositories state.
If we don't want to depend on all the patches then, just like record
, we can
instruct tag
to prompt us for dependencies by adding the --ask-deps
flag to
our command. So in case we just want to depend on patch A
for our tag we can
simply do this.
$ darcs tag -m 1.0 --ask-deps
patch 773190b27402bae8af4895db5810010650652185
Author: raichoo@example.com
Date: Wed Jul 11 19:14:46 CEST 2018
* A
Shall I depend on this patch? (1/2) [ynW...], or ? for more options: y
patch 4dd3f2b240fcae41674f6742213c0ac953981aa7
Author: raichoo@example.com
Date: Wed Jul 11 19:15:28 CEST 2018
* B
Shall I depend on this patch? (2/2) [ynW...], or ? for more options: n
Do you want to Depend on these patches? [Yglqk...], or ? for more options: y
Finished tagging patch 'TAG 1.0'
To list all the tags in a repository you can issue darcs show tags
and it will
give a list of all the recorded tags.
This is especially useful if we decide to tag
our repository but already
recorded some patches that we don't want to have in that version.
Now if we wanted to pull in all the changes the correspond to our tag
1.0
from another repository we can specify that tag
by using the -t
flag that
pull offers. This is where tags become quite helpful if we just care about a
specific version on the project. Maybe we want to retrieve a stable version of a
piece of software without pulling in the patches that or not yet part of a
stable release.
Here we are in repository that only contains patch B
and we want to pull in
all the dependencies of our tag
1.0
. This is how we would go about that.
$ darcs log
patch 4dd3f2b240fcae41674f6742213c0ac953981aa7
Author: raichoo@example.com
Date: Wed Jul 11 19:15:28 CEST 2018
* B
$ darcs pull -t 1.0 ../repo
Pulling from "/tmp/darcs/repo"...
patch 773190b27402bae8af4895db5810010650652185
Author: raichoo@example.com
Date: Wed Jul 11 19:14:46 CEST 2018
* A
Shall I pull this patch? (1/2) [ynW...], or ? for more options: y
patch 46094731f678f0741907b99b3bedeaff5febd27d
Author: raichoo@example.com
Date: Wed Jul 11 19:18:29 CEST 2018
tagged 1.0
Shall I pull this patch? (2/2) [ynW...], or ? for more options: y
Do you want to Pull these patches? [Yglqk...], or ? for more options: y
Finished pulling.
$ darcs log
patch 46094731f678f0741907b99b3bedeaff5febd27d
Author: raichoo@example.com
Date: Wed Jul 11 19:18:29 CEST 2018
tagged 1.0
patch 773190b27402bae8af4895db5810010650652185
Author: raichoo@example.com
Date: Wed Jul 11 19:14:46 CEST 2018
* A
patch 4dd3f2b240fcae41674f6742213c0ac953981aa7
Author: raichoo@example.com
Date: Wed Jul 11 19:15:28 CEST 2018
* B
If there are any patches in that other repository that are not a dependency of
1.0
we would not be prompted for those.
Actually the -t
flag is supported by quite a lot of darcs
commands. If you
took a look at all of the available options for all of the darcs
commands you
might have realized that darcs
is trying very hard to give you a consistent
user experience. If a command understands the notion of a tag
those will
always be references with the -t
flag or its longhand --tags
. This flag
takes a regular expression so you can even reference multiple tags at once if
you happen to fancy that in a particular situation.
It should not be much of a surprise that push
supports the -t
flag as well,
so if we were to push
our changes in the above example we would do it like
this.
$ darcs push -t 1.0 ../anotherrepo
patch 773190b27402bae8af4895db5810010650652185
Author: raichoo@example.com
Date: Wed Jul 11 19:14:46 CEST 2018
* A
Shall I push this patch? (1/2) [ynW...], or ? for more options: y
patch 46094731f678f0741907b99b3bedeaff5febd27d
Author: raichoo@example.com
Date: Wed Jul 11 19:18:29 CEST 2018
tagged 1.0
Shall I push this patch? (2/2) [ynW...], or ? for more options: y
Do you want to Push these patches? [Yglqk...], or ? for more options: y
Finished applying.
Push successful.
Ah, nice and consistent. Everything is just as we expected.
When using darcs show dependencies
things might become a little surprising
because this command only generates a graph by walking backwards through our
repository's history until it encounters the first tag. So if we were to look at
our repository right after we have tagged a version which depends on all the
loose ends in our patch dependency graph things might get a little
anti-climactic. We might end up with a "graph" that looks like this.
This is actually how it is supposed to look because darcs show dependencies
only looks at past patches until it finds a tag
. But things might get a bit
confusing if we hand craft our tag dependencies. This is how our dependency
graph would look like after our darcs tag -t 1.0 --ask-deps
example, where we
only let the tag
1.0
depend on patch A
and not B
.
Now that's quite weird. Even though we have tagged our repository we still can
see past tag
1.0
. Wasn't darcs show dependencies
supposed to stop when it
encountered the first tag? This is because our history currently looks like
this.
$ darcs log -v
patch d457a1cbaa6ad18761849fc7a90589dc3cdeb108
Author: raichoo@example.com
Date: Wed Jul 11 22:07:27 CEST 2018
tagged 1.0
depend patch 773190b27402bae8af4895db5810010650652185
* A
patch 4dd3f2b240fcae41674f6742213c0ac953981aa7
Author: raichoo@example.com
Date: Wed Jul 11 19:15:28 CEST 2018
* B
addfile ./B
patch 773190b27402bae8af4895db5810010650652185
Author: raichoo@example.com
Date: Wed Jul 11 19:14:46 CEST 2018
* A
addfile ./A
So there is a patch, namely B
that is not part a dependency of 1.0
but it's
still in our repository and history-wise it's after our tag
. darcs
is trying
very hard to make a useful graph out of this situation and this is the best it
can come up with. This is what's called a dirty tag, and they can impact the
performance of commands where repositories need to be compared such like pull
and push
. Thankfully we can get rid of these dirty tags quite easily by
moving all the patches that are not a dependency of our tag
to the top of our
history. This is what darcs optimize reorder
does. Take a look.
$ darcs optimize reorder
Done reordering!
$ darcs log
patch 4dd3f2b240fcae41674f6742213c0ac953981aa7
Author: raichoo@example.com
Date: Wed Jul 11 19:15:28 CEST 2018
* B
patch d457a1cbaa6ad18761849fc7a90589dc3cdeb108
Author: raichoo@example.com
Date: Wed Jul 11 22:07:27 CEST 2018
tagged 1.0
patch 773190b27402bae8af4895db5810010650652185
Author: raichoo@example.com
Date: Wed Jul 11 19:14:46 CEST 2018
* A
Ah that's better now darcs
can make a bit more sense of our history and create
a nice crisp dependency graph that looks just like we expect it.
B
now comes before 1.0
in our history, in fact there is nothing hiding past
the tag
that is not a dependency 1.0
. So darcs
can stop generating the
graph right after encountering our tag
, it's not dirty anymore. Notice that
darcs optimize reorder
does not change the identity of a patch. This is once
again a result of darcs
not really caring about the order in which patches get
applied to your repository.
Tags are particularly useful when cloning a repository. If you ever want to
check out a specific version of a repository you can specify a tag
with -t
just like with any other command and get a copy of the project from that
version. Let's say that out of curiosity we want to take a look at version
1.0.0
of darcs
. Since I have a copy of the darcs
repository on my computer
I can do it like this.
$ darcs clone -t 1.0.0 --lazy darcs-screened darcs-old
Going to specified version...
Unapplying 10084 patches
Finished cloning.
This work flow can be used to branch off from a specific version and work from
there. Some development models feature multiple branches. Maybe you have a
release
branch that contains all the patches you ship to your audience and a
development
branch where you try out new things. Once your development
branch has stabilized you can tag
a version and pull
that into your stable
branch. darcs
unlike other version control systems does not have a notion of
branches, we simple maintain multiple working trees. If you are worried that
this might take up an unreasonable amount of disk space don't worry too much.
darcs
is able to share information between these copies so cloning a local
repository is pretty fast and does not take twice as much disk space as you
might expect.