< Return to Video


  • 0:00 - 0:02
    Thank you very much.
  • 0:03 - 0:05
    Thanks everybody for coming,…
  • 0:09 - 0:12
    If you are packaging software and you want
    me to work on with you,
  • 0:12 - 0:14
    this is how you can do that.
  • 0:14 - 0:15
    It is a very self-??? talk:
  • 0:15 - 0:19
    I just want to explain some of the things
    that I like,
  • 0:19 - 0:21
    some practice that I prefer about Debian
  • 0:21 - 0:25
    and I don't pretend this is any sort of…
  • 0:25 - 0:27
    official, permanent or final thing.
  • 0:27 - 0:30
    I just wanted to share some ideas that I
    have about the way that I work with
  • 0:30 - 0:35
    packages, in the hope that maybe, hmm,
    for two hopes:
  • 0:35 - 0:38
    One is that I hope that I can show you
    something that you have not heard of,
  • 0:38 - 0:41
    or maybe you were doing differently,
  • 0:41 - 0:42
    or maybe you think it is
    the right think to do
  • 0:42 - 0:44
    and it is just nice to see
    somebody else doing it.
  • 0:44 - 0:47
    My second hope is that you can tell me
    what I am doing wrong,
  • 0:47 - 0:51
    and you can help me learn and improve
    on my own packaging techniques.
  • 0:51 - 0:53
    If you see something that
    I am proposing up here,
  • 0:53 - 0:56
    and you think there is a problem with it,
    I would like to hear about it too.
  • 0:56 - 0:58
    I just want to see more of the culture
    within Debian,
  • 0:58 - 1:01
    of people who are doing packaging,
    explaining what they are doing,
  • 1:01 - 1:03
    and so I thought I would
    just step up and explain:
  • 1:03 - 1:04
    "Here is some of the practice that I do",
  • 1:04 - 1:09
    In the hope that other people will do the
    same and explain what they are doing,
  • 1:09 - 1:12
    and maybe they can learn from
    me and I can learn from them.
  • 1:12 - 1:17
    Without much further ????, I am
    just going to dive into it.
  • 1:17 - 1:21
    If you have questions, I am perfectly
    happy to be interrupted,
  • 1:21 - 1:24
    we have some folks with walking mics
    in the crowd:
  • 1:24 - 1:27
    you can just raise your hand.
  • 1:27 - 1:29
    If you have got a question or an
    interruption or whatever,
  • 1:29 - 1:30
    that is fine.
  • 1:30 - 1:33
    I doubt I will go the whole 15 minutes,
    I think there are 20 minutes,
  • 1:33 - 1:35
    I doubt I will go the whole time,
    so there will be also
  • 1:35 - 1:37
    time for questions at
    the end if you prefer.
  • 1:37 - 1:39
    But I do not mind being interrupted.
  • 1:39 - 1:43
    So, this is all on this web page here,
  • 1:43 - 1:45
    you could probably skip this talk and go
    read the web page,
  • 1:45 - 1:47
    but then you would not have the nice
    ??? actions,
  • 1:47 - 1:49
    and it is easier to tell me that I am
    wrong in person,
  • 1:49 - 1:51
    so I would like to have that happen.
  • 1:51 - 1:53
    I put this up on the Debian wiki,
  • 1:53 - 1:56
    because I want anyone
    to be able to find it.
  • 1:56 - 2:00
    If you think you have got some good ideas,
    you should put it on the Debian Wiki too:
  • 2:00 - 2:05
    other people can take advantage of the
    ideas that you have got.
  • 2:08 - 2:11
    First baseline is:
    I really like revision control.
  • 2:11 - 2:14
    And I know that it makes me
    a certain flavor on nerd,
  • 2:14 - 2:19
    but when we are working with things that
    are as complicated as software packages,
  • 2:19 - 2:20
  • 2:23 - 2:26
    I think a lot of people don't get
    that in Debian you are not
  • 2:26 - 2:28
    just working on one
    software package:
  • 2:28 - 2:30
    you are actually probably, if you
    are doing a responsibly work,
  • 2:30 - 2:33
    on at least two software packages,
    and maybe 5.
  • 2:33 - 2:35
    So you have got the version that is
  • 2:35 - 2:39
    and you have got the version that you
    try to maintain for stable as well.
  • 2:39 - 2:45
    And we are committing to
    doing maintenance work.
  • 2:45 - 2:52
    A lot of our work in the project is ???
    in nature:
  • 2:52 - 2:55
    we want to clean up the mess and
    we want us to stay out of the way
  • 2:55 - 2:58
    and make sure things work,
  • 2:58 - 3:01
    for people who are relying on the
    operating system to not get in their way.
  • 3:01 - 3:04
    So revision control I think is really
    helpful because it means you can
  • 3:04 - 3:08
    keep track of what changes you have done
    on different branches of the project
  • 3:08 - 3:10
    while you are maintaining both of them.
  • 3:10 - 3:14
    Basically, ??? require working with
    the revision system I am comfortable with,
  • 3:14 - 3:18
    I prefer Git, I am not going to have a
    religious word about it.
  • 3:18 - 3:21
    If upstream uses Git, I am
    even happier, and I try to make
  • 3:21 - 3:26
    my packaging depend on
    upstream's revision control.
  • 3:29 - 3:35
    I like to use 'git-buildpackage', and I
    like to use it with debhelper.
  • 3:35 - 3:37
    If you have not tried out
  • 3:37 - 3:40
    we are going to have a
    'git-buildpackage' skill share session
  • 3:40 - 3:44
    later on today actually, and I welcome
    you to come and share your tricks with it,
  • 3:44 - 3:46
    or learn some tricks from other people.
  • 3:46 - 3:50
    It is a particular way that you can keep
    your Debian packaging in a Git repository,
  • 3:50 - 3:56
    and it helps you to keep track of all of
    the changes that have happened within
  • 3:56 - 4:00
    your packaging and within upstream to
    make sure you are not accidentally
  • Not Synced
    making other changes.
  • Not Synced
    So it is very easy to go back and review
    what you have done.
  • Not Synced
    I find that really useful.
  • Not Synced
    I definitely also like to keep upstream's
    source code in the same revision control
  • Not Synced
  • Not Synced
    I like to keep the tarballs in the
    revision control system because it means
  • Not Synced
    that if someone is interested, they can
    uses a tool called 'debcheckout'.
  • Not Synced
    You can use 'debcheckout' with a name of
    a package:
  • Not Synced
    you say just "I am really interested in
    package 'foo',
  • Not Synced
    let me see the source code for that":
  • Not Synced
    debcheckout foo
  • Not Synced
    You get the source code, and you get the
    source code from a revision control
  • Not Synced
    system that you can now track and you
    can just propose changes on.
  • Not Synced
    You can also extract the tarball from that
    revision control system.
  • Not Synced
    'debcheckout' actually works even if you
    do not have upstream stuff in there,
  • Not Synced
    but I like to keep it all in one revision
    control system,
  • Not Synced
    it is just easier to find everything when
    you want.
  • Not Synced
    Some of these things that I prefer have
    to do with what the upstream software
  • Not Synced
    developer has done, so I am less inclined
    to try the package an upstream software
  • Not Synced
    project if they just throw tarballs here
    over the wall to an FTP side
  • Not Synced
    every now and then.
  • Not Synced
    It makes it more difficult for me to know
    what they are doing,
  • Not Synced
    and why they are doing it.
  • Not Synced
    So i like it, I have already said, when
    upstream uses Git,
  • Not Synced
    I also like when upstream signs their
  • Not Synced
    and say "hey, this is specific release",
  • Not Synced
    Because that is a signal that I can use,
    or somebody else that understands the
  • Not Synced
    project: as said "we think that this
    something that other people can use",
  • Not Synced
    or "this is a particular version we would
    like other people to test".
  • Not Synced
    There are a lot of other situations where
    maybe it is not so important.
  • Not Synced
    And having that be cryptographically
    signed is really useful.
  • Not Synced
    I care about cryptographic signature on
    software because I want to know that
  • Not Synced
    what I am running is related to the code
    that somebody else out should be run.
  • Not Synced
    And if you don't verify your software
    cryptographically, anyone could
  • Not Synced
    intercept the network connection
    between you and that software,
  • Not Synced
    and modify the software before it gets
    to you.
  • Not Synced
    And the cryptographic signature just says:
  • Not Synced
    "look, this is a version that I am OK
    with. I am putting it out there and
  • Not Synced
    it comes from me".
  • Not Synced
    And so I can have a trace back to that
  • Not Synced
    ??? just talk about briefly about how you
    do cryptographic verification of upstream.
  • Not Synced
    You might know upstream: you might know
    them personally, you know their key
  • Not Synced
    already, that is fine.
  • Not Synced
    That is not the usual case: we work on
    the Internet.
  • Not Synced
    In the situation where your upstream is
    signing their tarballs
  • Not Synced
    and you have not met them, you do not
    have to sign their key,
  • Not Synced
    you do not have to say "I announce this
    is their key".
  • Not Synced
    This is probably the same one that is
    signing every release,
  • Not Synced
    so you should keep track of that.
  • Not Synced
    Debian has a nice way to keep track of
  • Not Synced
    you can tell Debian how to find the new
    version of the upstream tarball.
  • Not Synced
    This is in the Debian 'watch' file.
  • Not Synced
    If you type 'man uscan', you can learn
    more about Debian 'watch',
  • Not Synced
    and Debian 'watch' has now a feature that
    lets you say
  • Not Synced
    "that is not only this way you find the
  • Not Synced
    but upstream publishes signatures
    and the signatures look like this".
  • Not Synced
    You know, they got a '.sig' at the end.
  • Not Synced
    So there is a particular arcane way to
    specify that, but if you specify that,
  • Not Synced
    then 'uscan' can find not only the
    upstream tarball but can find the
  • Not Synced
    upstream signature and, if you drop
    upstream's signing key -
  • Not Synced
    which of course I did not put on the wiki
    page, someone should add it that and
  • Not Synced
    fix it - you can put the upstream signing
    key in 'debian/upstream/signing-key.asc'.
  • Not Synced
    And then if you do that, when you say
    'uscan', you can tell…
  • Not Synced
    Maybe some people here do notk
    now how to use 'uscan'.
  • Not Synced
    'uscan' is a very simple tool,
    you run it from a software package that
  • Not Synced
    has a 'debian' directory, or even one
    level up if you keep all of your software
  • Not Synced
    packages in one folder. You can go one
    level up and say 'uscan', and it will look
  • Not Synced
    in all of the folder that are children
    of it, and look for new version by
  • Not Synced
    trying to find for new upstreams versions
    in 'debian/watch'.
  • Not Synced
    And if you have configured 'debian/watch'
    properly, it can find the new upstream
  • Not Synced
    signatures, and if you have got the
    'upstream/signing-key.asc', then
  • Not Synced
    it will actually verify the signature for
    you as part of fetching the new
  • Not Synced
    upstream tarball.
  • Not Synced
    So you can get all of those things just
    by setting ???? that way.
  • Not Synced
    There is a hand up down there, could we
    get the mic down to the hand ?
  • Not Synced
    Or to the person who has that hand, it is
    not just a hand. [public laugh]
  • Not Synced
    [someone] Publish a tarball and a hash, '.sha1',
    and sign that hash, '.sha1.asc'.
  • Not Synced
    Can 'uscan' cope with this and check the
    signature on the hash and that the hash
  • Not Synced
    belongs to that tarball ?
  • Not Synced
    [Daniel] I do not believe that 'uscan' can
    do that currently. So anybody out there
  • Not Synced
    who wants to make things better for the
    world should go hack on 'uscan':
  • Not Synced
    that is a pretty straightforward thing
    that we should fix because I agree
  • Not Synced
    that is common pattern.
  • Not Synced
    [someone] I have no answer to this
    question by I have another question:
  • Not Synced
    how do you convince upstreams who do
    not release tarballs or who do
  • Not Synced
    not set tags in Git ?
  • Not Synced
    [Daniel] Who do not make tags in Git ?
  • Not Synced
    [someone] Yes, if there is no tags you
    can not check out a tarball.
  • Not Synced
    Is there any good way to convince
    upstream to do this ?
  • Not Synced
    [Daniel] Git has this nice feature, which
    is that you can create a tag,
  • Not Synced
    which is associate with a particular
  • Not Synced
    and you would like to have a tag
    everywhere that a tarball has been
  • Not Synced
    released from. I am tempted to pull up
    a Git view and show people some tags.
  • Not Synced
    The question that you ask is a social
    one, not just a technical one,
  • Not Synced
    and I actually find that my upstreams
    are pretty responsive.
  • Not Synced
    Usually I frame my request as "hey, it
    looks like you made this tarball from
  • Not Synced
    this particular commit 'id'. If you could
    tag you releases, it would be really
  • Not Synced
    helpful to me, and here is the command
    that I would use to tag the release".
  • Not Synced
    And I say "git tag…" and of course I
    can never remember so first I look it up,
  • Not Synced
    but it is either 'tag name' 'commit id' or
    'commit id' 'tag name'.
  • Not Synced
    But I would look it up and I would write
    the e-mail so that all they have to do is
  • Not Synced
    they read it, understand my argument,
    and execute one command.
  • Not Synced
    And then it starts them ??????
  • Not Synced
    And if you say 'tag -s' then your tag will
    be cryptographically signed, which
  • Not Synced
    I think is a really good thing to do too.
  • Not Synced
    So, cryptographic verification of
  • Not Synced
    As I said, I want to keep upstream's code
    in the revision control system.
  • Not Synced
    I also like to keep…
  • Not Synced
    In my ideal case upstream is using Git:
    I am using Git for packaging.
  • Not Synced
    I actually like to keep upsteam's Git
    history fully in my repository,
  • Not Synced
    so that I do not just have the tarballs,
    but I actually have all of their commits.
  • Not Synced
    And that turns out to be really useful
    for two specific cases:
  • Not Synced
    In one case, there is a common scenario
    where upstream will fix a bug,
  • Not Synced
    but they have not made a release yet.
  • Not Synced
    And that bug is really, really obviously
    problematic for the folks who are
  • Not Synced
    using Debian, so want to fix it.
  • Not Synced
    All I can do, because I have their full
    revision history, I can use Git to "cherry
  • Not Synced
    pick" the upstream commit.
  • Not Synced
    And then I "cherry pick" that upstream
    commit and I can have it applied
  • Not Synced
    separately and release an Debian version
    that has the fix, even before upstream
  • Not Synced
    has made a release with the fix.
  • Not Synced
    So one nice thing about having upstream
    revision is that I can pull fixes from
  • Not Synced
    upstream before they decided
    to release it.
  • Not Synced
    The other advantage is the other
    way around.
  • Not Synced
    Often when I am doing packaging,
    I discover a problem,
  • Not Synced
    and maybe I can fix the problem.
  • Not Synced
    And if that maybe I am already shipping
    a Debian package that fixes the problem.
  • Not Synced
    If my Debian fixes can be directly applied
    to upstream, then I can use whatever
  • Not Synced
    their preferred upstream patch
    submission guidelines are,
  • Not Synced
    whether it is a Github pull request, or
    a patch to a mailing list,
  • Not Synced
    or a "hey can you pull this from my Git
    repository over here", e-mail…
  • Not Synced
    The fact that I am using the same Git
    history that they are using makes it
  • Not Synced
    much easier for me to push my changes
    back to them.
  • Not Synced
    So, it sort of smooth the interaction if
    you can consolidate and use the same
  • Not Synced
    revision control system as their.
  • Not Synced
    Towards that aim, I use a system now
    called 'patch q',
  • Not Synced
    which is part of 'git buildpackage'.
  • Not Synced
    So 'git buildpackage' is 'gbp', 'patch q'
    is 'pq',
  • Not Synced
    so to deal with 'patch q' you say
    'gbp pq'
  • Not Synced
    and then you have some commands.
  • Not Synced
    And what that does, is it takes…
  • Not Synced
    How many of you are Debian packagers ?
  • Not Synced
    How many of you package
    software for Debian ?
  • Not Synced
    A very large percentage, but not everyone.
  • Not Synced
    I hope some folks are considering starting
    packaging if you have not done it yet.
  • Not Synced
    Of those of you who package software,
    how many of you package software
  • Not Synced
    with modifications, how many of you ship
    a modified version of upstream sources ?
  • Not Synced
    Beyond the 'debian' directory, just Debian
    patches ?
  • Not Synced
    So the common way to do that, for the
    Debian 3.0 ??? packaging skill, is that in
  • Not Synced
    your 'debian' directory you have a
    'patches' sub-directory that has a set of
  • Not Synced
    individual patches that apply certain
    changes, and they are applied in order
  • Not Synced
    based on the file called
  • Not Synced
    So maintaining that is kind of a drag
    when upstream makes big changes:
  • Not Synced
    then all of sudden you have got this set
    of patches and they do not quite apply…
  • Not Synced
    I is a drag even you do not have it in
    the 'debian/patches/' directory.
  • Not Synced
    But what Debian 'patch q' does is it maps
    that directory of patches into a little
  • Not Synced
    branch on your Git revision history.
  • Not Synced
    So when you get a new upstream version,
    you can say 'patch q rebase',
  • Not Synced
    and it treats it just as Git: it takes the
    'patch q'…
  • Not Synced
    You have already imported the new version,
    and it re-applies your patches,
  • Not Synced
    and sometimes that means some minor
  • Not Synced
    Git is really good at figuring out what
    the right minor adjustments are to make,
  • Not Synced
    and so all of the sudden the 'patch q' is
    re-based, you refresh it in your revision
  • Not Synced
    control system, and there you go.
  • Not Synced
    So I like to use 'git-buildpackage' 'patch q',
    tagging, as already brought up,
  • Not Synced
    thank you for that, I like to to tag
    everything that I release,
  • Not Synced
    I like to push that as soon as I can,
    so that other people who are following
  • Not Synced
    my work can now where my releases
    come from.
  • Not Synced
    The reason that I like other people
    following my work is
  • Not Synced
    they can fix my bugs easier.
  • Not Synced
    I make mistakes, everybody makes mistakes,
    and it is really important to me that
  • Not Synced
    if someone catches one of my mistakes,
    I can accept their feedback,
  • Not Synced
    their criticism, their improvements,
    as easily as possible.
  • Not Synced
    I want a low barrier to entry for people
    to help me fix my problems,
  • Not Synced
    it is selfishness. So I try to patch it
    and publish this things for people
  • Not Synced
    can find it.
  • Not Synced
    I am ??? on these pretty fast because
    were are almost at the time.
  • Not Synced
    I like to put in some place where other
    people get to the them,
  • Not Synced
    at the moment I like to put them in
  • Not Synced
    it has some problems but it is better
    than not publishing your stuff,
  • Not Synced
    and it is nice because it is sort of
    a public use.
  • Not Synced
    I like to standardize how of my branches
    are named, so if I am working on
  • Not Synced
    something that has got a stable version,
    that is for Jessie, I will name the branch
  • Not Synced
    'jessie', because I ???
  • Not Synced
    ???? multiple branches ???
  • Not Synced
    I try to push as frequently as I have made
    something that looks sensible.
  • Not Synced
    I do not feel obliged to push my commits
    to a public repository when I am still
  • Not Synced
    experimenting, I actually really like to
    experiment, and I also like to keep track
  • Not Synced
    of my experiments while I am doing them.
  • Not Synced
    So I try to push when there is a sensible
    set of changes, and I am trying to get
  • Not Synced
    myself to a point where I can understand
    what I have done, even if it wrong.
  • Not Synced
    If I can get myself to a conceptual point
    where it is done, I will push my changes
  • Not Synced
    so other people can see what I am
    working on, and then work from there.
  • Not Synced
    That is OK to push something that is
  • Not Synced
    as long as you push something that
    people can understand.
  • Not Synced
    When you make a 'git commit' (if you are
    working with Git),
  • Not Synced
    One of the things that helps me to think
    about commit messages…
  • Not Synced
    People often think that commit messages
    should say "what change you made".
  • Not Synced
    I think that the 'git patch' shows what
    change what change you have made,
  • Not Synced
    and I thin your commit messages should
    say "why you made the change".
  • Not Synced
    That is what people really want to read.
  • Not Synced
    If you need to explain technically why
    the thing that you did
  • Not Synced
    maps to the conceptual thing that you
    wanted to do, that is fine:
  • Not Synced
    do that in your commit message too.
    But it is really important to say why
  • Not Synced
    you made the change. It is not just like
    "initialize variable to 'no'":
  • Not Synced
    OK, we can see that from the patch,
    but you what you are really saying
  • Not Synced
    is "there was a crash if someone did 'x',
  • Not Synced
    and we are avoiding that crash by
    setting this to 'no'.
  • Not Synced
    So I like to send patches via email,
  • Not Synced
    so I try to configure Git email, which
    make it really easy to just
  • Not Synced
    push patches back upstream.
  • Not Synced
    If I am starting taking over a project
    that somebody else has past on,
  • Not Synced
    and they did not use Git, I will try to
    restore all of the imports.
  • Not Synced
    I would be happy to talk with people
    about how to do that,
  • Not Synced
    if you have questions come find me.
  • Not Synced
    I like to keep my files ???? simple:
    there is a tool 'wrap-and-sort',
  • Not Synced
    that just canonicalizes your files to
    make them look in a simple and
  • Not Synced
    sensible way. And it is nice because it
    means that everything is…
  • Not Synced
    It does things like alphabetize your
    list of build depends,
  • Not Synced
    and brake them out one per line.
    The nice thing about that,
  • Not Synced
    since you are using revision control,
    when you make a change
  • Not Synced
    to your build depends, the changes
    become very easy to see:
  • Not Synced
    "oh, they added one new package here,
    there is a single '+'".
  • Not Synced
    When ???? so you can see that kind of
  • Not Synced
    I like to use ? deb five ? to format
    Debian copyright to be machine readable,
  • Not Synced
    it is nice for people who are doing scans
    of the archive and try reason about
  • Not Synced
    what the patterns are, and licensing of
    free software.
  • Not Synced
    And if I am doing something really crazy,
    that is going to make a big change,
  • Not Synced
    I like to use a feature branch in
    revision control.
  • Not Synced
    So we have got one minute left,
    I want to open it up for other questions.
  • Not Synced
  • Not Synced
    [attendee] You said you are using
    'wrap-and-sort' which is nice,
  • Not Synced
    I had learned that ???? editors
    - 'cme' - do the same job,
  • Not Synced
    and somehow does a better job:
    it also ??? standard version
  • Not Synced
    if it does not fit, or it makes VCS
    fields properly has it should be.
  • Not Synced
    'cme fix dpkg-control' fixes your
    control file.
  • Not Synced
    [Daniel] 'cme' ? And it is in
    what package ?
  • Not Synced
    [attendee] The package 'cme', in
    unstable ????. In Jessie it is ????
  • Not Synced
    [Daniel] You are developing in unstable,
    that is OK.
  • Not Synced
    OK, thank you.
  • Not Synced
    Other questions or suggestions,
    or complains ?
  • Not Synced
    [attendee] If you change the original
    source code, and do some commits,
  • Not Synced
    how do you convert that into a series
    of ??? patches ?
  • Not Synced
    [Daniel] I use 'patch q' for that as well,
    so what I do is I say
  • Not Synced
    "I want to move over to my 'patch q'
    view of the tree",
  • Not Synced
    and then I make may changes, I make
    my commits,
  • Not Synced
    and then I say
    'gbp pq export',
  • Not Synced
    and it takes the 'patch q' that I am on
    and dumps it back
  • Not Synced
    into the Debian patches directory.
  • Not Synced
    If you have not use 'gbp pq', I
    recommend looking into it.
  • Not Synced
    It takes a little while to get used to,
    and I still screwed it up sometimes,
  • Not Synced
    but it makes easy to fix your
    mistakes too.
  • Not Synced
    [organizer] Last question ?
  • Not Synced
    [attendee] Do you think it is possible to
    make this 'patch q' branch
  • Not Synced
    "pullable" by upstream ?
  • Not Synced
    [Daniel] I do not actually think it is
    possible to make it directly
  • Not Synced
    "pullable" by upstream: I think upstream
    can cherry pick patches from it,
  • Not Synced
    but I do not see how to
    make it "pullable".
  • Not Synced
    If someone else does, I would be
    happy to learn.
  • Not Synced
    [organizer] This was "before last",
    so last.
  • Not Synced
    [attendee] Do you have a recording of
    you using the tools that you mentioned,
  • Not Synced
    a video recording would be great,
    just to show your workflow ?
  • Not Synced
    [Daniel] I do not really know how
    to do that: if somebody wants to
  • Not Synced
    help me do that I would be
    happy to do it.
  • Not Synced
    I am going to give one last plug,
  • Not Synced
    I know we are out of time here,
  • Not Synced
    This tool is called 'gitk'.
  • Not Synced
    This is an example - sorry we
    should leave - but this the way
  • Not Synced
    that I visualize my revision
    control system.
  • Not Synced
    We could do a whole other session
    about 'gitk'.
  • Not Synced
    If you do not try to visualize your
    revision control system,
  • Not Synced
    you are missing out: try to find a way
    to visualize stuff,
  • Not Synced
    find one that works for you.
  • Not Synced
    Thanks for coming.
  • Not Synced
    [organizer] Thank you.
Video Language:

English subtitles

Revisions Compare revisions