The Hackerlab at regexps.com

Patch Logs and Project Tree History

up: arch Meets hello-world
next: Development Branches -- The star-merge Style of Cooperation
prev: Elementary Branches -- Maintaining Private Changes

In the previous chapter, we began to learn about branching and merging. We saw how commands like missing , update , and replay can be used to keep track of and apply changes from multiple branches of a project.

In this chapter, we'll explain a bit about patch logs : the mechanism that is used to keep track of the history of a project tree, including that part of the history that is used for intelligent merging.

You should recall first encountering patch logs in earlier chapters (for example, when first initializing a project tree, in Starting a New Source Tree). In this chapter, patch logs are explained in greater depth.

Project Trees Have Patch Logs

Recall that every initial import, tag revision, and changeset revision in an archive has an associated log message. That message consists of the headers and body that you supply to commands such as import and commit , plus additional headers that are automatically generated by arch .

When a project tree is first imported to an archive, the patch log entry for the new revision is added to the tree. When a commit takes place, as part of the process of committing, the log entry for the new revision is added to the tree. If you get a revision created by the tag command, you'll also find that it contains a patch log entry for the tag revision.

Patch log entries accumulate. Thus, for example, each commit adds a new log entry and all earlier log entries are preserved. Each tag revision includes not only the entry for the tag, but all log entries inherited from the revision being tagged.

Returning to our earlier examples, let's take a look at Alice and Bob's patch-2 revision:


        % cd ~/wd

        [... remove directories from earlier examples ...]

        % tla get -A lord@emf.net--2003-example \
                    hello-world--mainline--0.1--patch-2 \
                    hw-AnB-2

        [...]

        % cd ~/hw-AnB-2


First, we note that patch logs are sorted by arch version names. This tree has logs from only one version:


        % tla log-versions
        lord@emf.net--2003-example/hello-world--mainline--0.1


Within that version, it has logs for the initial import, and two changesets:


        % tla logs -A lord@emf.net--2003-example \
                       --summary \
                       hello-world--mainline--0.1
        base-0
            initial import
        patch-1
            Fix bugs in the "hello world" string
        patch-2
            commented return from main


Examining one of those log entries in particular:


        % tla cat-log -A lord@emf.net--2003-example \
                        hello-world--mainline--0.1--patch-2
        Revision: hello-world--mainline--0.1--patch-2
        Archive: lord@emf.net--2003-example
        Creator: Tom (testing) Lord <lord@emf.net>
        Date: Wed Jan 29 12:46:50 PST 2003
        Standard-date: 2003-01-29 20:46:50 GMT
        Summary: commented return from main
        Keywords: 
        New-files: \
          {arch}/[...]/hello-world--mainline--0.1/[...]/patch-log/patch-2
        Modified-files: main.c
        New-patches: \
          lord@emf.net--2003-example/hello-world--mainline--0.1--patch-2

        Added a comment explaining how the return from `main'
        relates to the exit status of the program.



we can see, for example, that the patch-2 changeset modified the file main.c and added a new file, the log entry itself (whose name is abbreviated in the output displayed above).

Other examples worth considering come from Candice's tree. Recall that she used tag to fork from Alice and Bob's tree at their patch-1 revision. Therefore we see:


        % cd ~/wd

        % tla get -A candice@candice.net--2003-candice \
                    hello-world--candice--0.1--patch-2 \
                    hw-C-0

        [...]

        % cd ~/hw-C-0

        % tla log-versions
        candice@candice.net--2003-candice/hello-world--candice--0.1
        lord@emf.net--2003-example/hello-world--mainline--0.1

        % tla logs  -A lord@emf.net--2003-example \
                        --summary \
                        hello-world--mainline--0.1
        base-0
            initial import
        patch-1
            Fix bugs in the "hello world" string


        % tla logs  -A candice@candice.net--2003-candice \
                        --summary \
                        hello-world--candice--0.1
        base-0
            tag of \
              lord@emf.net--2003-example/hello-world--mainline--0.1--patch-1


How It Works -- missing

In earlier chapters, you learned how the command missing can tell you about changes commited to archives, but not yet present in a given project tree (see Studying Why Alice Can Not commit and Exploring the New Branch).

It should now be easy to understand how those commands work. arch can find the list of all revisions in a given version using the revisions command:


        % tla revisions -A lord@emf.net--2003-example \
                          hello-world--mainline--0.1
        base-0
        patch-1
        patch-2
        patch-3


Those are the logs in the archive. arch can find out the list of revisions for which a project tree has log entries with logs :


        % tla logs -A lord@emf.net--2003-example \
                       hello-world--mainline--0.1
        base-0
        patch-1
        patch-2


The difference between those two lists is the output of missing :


        % tla missing -A lord@emf.net--2003-example \
                      hello-world--mainline--0.1
        patch-3


The Concept of Change History and Tree Ancestry

Patch logs give important insight into the history of a tree. There are two views worth mentioning: the change history view, and the tree ancestry view.

Change History

When a tree has a log for a given commit changeset, that means that the changes from that commit have been applied to the tree: the commit changeset is part of the "change history" of the tree. If the changeset were a bug fix, for example, then this is a likely indication that the bug fix is present in the tree.

Note: The mere fact that a given changeset is part of the change history of a tree isn't absolute proof that the changes made by that changeset are present in the tree. For example, those changes might have been "undone" by a later change. Nevertheless, the change history of a tree is a useful tool for exploring and understanding its state.

Tree Ancestry

Informally, we say that an archived revision is a tree ancestor of a given project tree if it has patch log entries for all of the revisions in the version of that archived revision up to to the archived revision itself.

Thus, for example, Candice's tag revision has Alice and Bob's patch-1 revision as an ancestor because it has logs for Alice and Bob's revisions:

        base-0
        patch-1

And Candices's patch-2 revision, which merges in changes from Alice and Bob's patch-2 and patch-3 , has both of those additional revisions as ancestors (see Updating from a Branched-from Version).

Automated ChangeLogs

The command tla changelog generates a GNU-style ChangeLog file from a patch log:

        
  % cd ~/wd

  % tla get -A candice@candice.net--2003-candice \
              hello-world--candice--0.1 \
              hw-C-latest
  [....]

  % cd ~/wd/hw-C-latest

  % tla changelog
  # do not edit -- automatically generated by arch changelog
  # arch-tag: automatic-ChangeLog-- [...]
  #

  2003-01-30 GMT  Tom (testing) Lord <lord@emf.net>       patch-2

      Summary:
        merge from mainline sources
      Revision:
        hello-world--candice--0.1--patch-2
  
      Patches applied:
      
        * lord@emf.net--2003-example/hello-world--mainline--0.1--patch-3
           added copywrong statements
      
        * lord@emf.net--2003-example/hello-world--mainline--0.1--patch-2
           commented return from main
      
  
      new files:
       {arch}/ [...] /hello-world--mainline--0.1 [...] /patch-2
       {arch}/ [...] /hello-world--mainline--0.1 [...] /patch-3
  
      modified files:
       hw.c main.c
  
      new patches:
       lord@emf.net--2003-example/hello-world--mainline--0.1--patch-2
       lord@emf.net--2003-example/hello-world--mainline--0.1--patch-3
  
  
  2003-01-30 GMT  Tom (testing) Lord <lord@emf.net>       patch-1
  
      Summary:
        Punctuated the output correctly
      Revision:
        hello-world--candice--0.1--patch-1
  
      
      This program should say "hello, world" not "hello world".
      
  
      modified files:
       hw.c
  
  
  2003-01-30 GMT  Tom (testing) Lord <lord@emf.net>       base-0
  
      Summary:
        tag of lord@emf.net--2003-example/hello-world--mainline--0.1--patch-1
      Revision:
        hello-world--candice--0.1--base-0
  
      (automatically generated log message)
      
  
      new patches:
       lord@emf.net--2003-example/hello-world--mainline--0.1--base-0
       lord@emf.net--2003-example/hello-world--mainline--0.1--patch-1
  


Note that the generated ChangeLog includes a tagline . If you save the output of the changelog command in a project tree, either using tagline ids or giving it an explicit id that matches the tagline s id, the commands such as commit will automatically keep the ChangeLog up to date.

arch Meets hello-world: A Tutorial Introduction to The arch Revision Control System
The Hackerlab at regexps.com