@need 3200

@node Patch Logs and Project Tree History
@chapter Patch Logs and Project Tree History

@geindex patch log



In the previous chapter, we began to learn about branching and
merging.   We saw how commands like @code{whats-missing}, @code{update}, and
@code{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 @geindex patch logs
@dfn{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
@ref{Starting a New Source Tree}).   In this chapter, patch logs are
explained in greater depth.

@need 3200

@section Project Trees Have Patch Logs

@geindex logs

@geindex log-ls

@geindex cat-log



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 @code{import}
and @code{commit}, plus additional headers that are automatically generated
by @code{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 @code{commit}
takes place, as part of the process of committing, the log entry for
the new revision is added to the tree.   If you @code{get} a revision
created by the @code{tag} command, you'll also find that it contains a
patch log entry for the tag revision.


Patch log entries @emph{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 @code{patch-2} revision:

@example
@group

@end group
@group
        % cd ~/wd
@end group
@group

@end group
@group
        [... remove directories from earlier examples ...]
@end group
@group

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

@end group
@group
        [...]
@end group
@group

@end group
@group
        % cd ~/hw-AnB-2
@end group
@group

@end group
@end example

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

@example
@group

@end group
@group
        % larch logs
        lord@@emf.net--2003-example/hello-world--mainline--0.1
@end group
@group

@end group
@end example

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

@example
@group

@end group
@group
        % larch log-ls -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
@end group
@group

@end group
@end example

Examining one of those log entries in particular:

@example
@group

@end group
@group
        % larch 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>
@end group
@group
        Date: Wed Jan 29 12:46:50 PST 2003
        Standard-date: 2003-01-29 20:46:50 GMT
        Summary: commented return from main
        Keywords: 
@end group
@group
        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
@end group
@group

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


@end group
@end example

@noindent
we can see, for example, that the @code{patch-2} changeset modified the
file @code{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 @code{tag} to fork from Alice and Bob's tree at their
@code{patch-1} revision.  Therefore we see:

@example
@group

@end group
@group
        % cd ~/wd
@end group
@group

@end group
@group
        % larch get -A lord@@emf.net--2003-candice \
                    hello-world--candice--0.1--patch-2 \
                    hw-C-0
@end group
@group

@end group
@group
        [...]
@end group
@group

@end group
@group
        % cd ~/hw-C-0
@end group
@group

@end group
@group
        % larch logs
        lord@@emf.net--2003-candice/hello-world--candice--0.1
        lord@@emf.net--2003-example/hello-world--mainline--0.1
@end group
@group

@end group
@group
        % larch log-ls  -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
@end group
@group


@end group
@group
        % larch log-ls  -A lord@@emf.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
@end group
@group

@end group
@end example



@need 3200

@section How It Works -- whats-missing

In earlier chapters, you learned how the command @code{whats-missing} can
tell you about changes commited to archives, but not yet present in a
given project tree (see @strong{Studying Why Alice Can Not commit} in @ref{The update/commit Style of Cooperation} and
@strong{Exploring the New Branch} in @ref{Elementary Branches -- Maintaining Private Changes}).


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

@example
@group

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

@end group
@end example

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

@example
@group

@end group
@group
        % larch log-ls -A lord@@emf.net--2003-example \
                       hello-world--mainline--0.1
        base-0
        patch-1
        patch-2
@end group
@group

@end group
@end example

The difference between those two lists is the output of
@code{whats-missing}:

@example
@group

@end group
@group
        % larch whats-missing -A lord@@emf.net--2003-example \
                              hello-world--mainline--0.1
        patch-3
@end group
@group

@end group
@end example



@need 3200

@section 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 @geindex change history
@dfn{change history} view, and the
@geindex tree ancestry
@dfn{tree ancestry} view.

@need 3200

@subsection Change History

When a tree has a log for a given @code{commit} changeset, that means that
the changes from that @code{commit} have been applied to the tree: the
@code{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.


@strong{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.







@need 3200

@section Tree Ancestry

Informally, we say that an archived revision is a @geindex tree ancestor
@dfn{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
@code{patch-1} revision as an ancestor because it has logs for Alice and
Bob's revisions:

@example
@group
        base-0
        patch-1
@end group
@group
@end group
@end example

And Candices's @code{patch-2} revision, which merges in changes from Alice
and Bob's @code{patch-2} and @code{patch-3}, has both of those additional
revisions as ancestors (see @strong{Updating from a Branched-from Version} in @ref{Elementary Branches -- Maintaining Private Changes}).




@need 3200

@section Automated ChangeLogs

@geindex changelog



The command @code{larch changelog} generates a GNU-style @code{ChangeLog} file from
a patch log:

@example
@group
        
@end group
@group
  % cd ~/wd
@end group
@group

@end group
@group
  % larch get -A lord@@emf.net--2003-candice \
              hello-world--candice--0.1 \
              hw-C-latest
  [....]
@end group
@group

@end group
@group
  % cd ~/wd/hw-C-latest
@end group
@group

@end group
@group
  % larch changelog
  # do not edit -- automatically generated by arch changelog
  # tag: automatic-ChangeLog-- [...]
  #
@end group
@group

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

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

@end group
@end example

Note that the generated @code{ChangeLog} includes a @code{tag} line.   If you 
save the output of the @code{changelog} command in a project tree, either
using implicit tags or giving it an explicit tag that matches the
@code{tag} line, the commands such as @code{commit} will automatically keep the
@code{ChangeLog} up to date.







