@need 3200

@node Inventory Ids for Source
@chapter Inventory Ids for Source

@strong{Caution: Steep Learning Curve:} As in the previous chapter, the
concepts and commands introduced here are likely to be unfamiliar to
you, even if you have used other revision control systems.   Once 
you "get it", though, this will seem quite natural.  Best of all,
this is the last tricky step before we can start storing project trees
in an archive.

@need 3200

@section Looks Like Source vs Really is Source

In the previous chapter, we saw how to find out which files look like
source according to the naming conventions:

@example
@group
        % tla inventory --names --source
        hw.c
        main.c
@end group
@group
@end group
@end example

In this chapter, there's a new distincition:  files which @emph{look} like
source according to their names, vs. files which @emph{really are} source.


When you save your project tree in an archive, arch will store the
files that @emph{really are} source and ignore the rest.  We can ask which
files really are source by dropping the @code{--names} option to
@code{inventory}:

@example
@group
        % tla inventory --source
        [no output]
@end group
@group
@end group
@end example

It's a little more interesting if we include arch's own "system
files and directories" in the listing:

@example
@group
        % tla inventory --source --all --both
        @{arch@}
        @{arch@}/.arch-project-tree
        @{arch@}/=tagging-method
        @{arch@}/hello-world
        [....]
@end group
@group
@end group
@end example

@noindent
but the thing to note here is that @code{hw.c} and @code{main.c} aren't listed.
Arch thinks they are source in name only.  The next section gives a
recipe to fix that, and the sections after that explain what's really
going on.




@need 3200

@section The add Command

We can tell arch that our files really are source, and should really
be archived with the project, using the @code{tla add} command:

@example
@group
        % tla add hw.c
        % tla add main.c
@end group
@group
@end group
@end example

And now we get a better answer from:

@example
@group
        % tla inventory --source
        hw.c
        main.c
@end group
@group
@end group
@end example

A related command is @code{tla delete}:

@example
@group
        % tla delete hw.c
@end group
@group
@end group
@end example

That doesn't delete the file @code{hw.c} itself:

@example
@group
        % ls
        hw.c            hw.c.~1~        main.c          @{arch@}
@end group
@group
@end group
@end example

@noindent
but it does remove it from the official list of source:

@example
@group
        % tla inventory --source
        main.c
@end group
@group
@end group
@end example

For the sake of the examples, we need to put @code{hw.c} back in the list:

@example
@group
        % tla add hw.c
@end group
@group
@end group
@end example
@example
@group
        % tla inventory --source
        hw.c
        main.c
@end group
@group
@end group
@end example

Let's take a deeper look at what's going on when you @code{tla add} files:




@need 3200

@section Two Names for Every File

In the @code{arch} world, every source file (and directory) in your project
tree has two names: a @geindex file path
@dfn{file path} and a @geindex inventory id
@dfn{inventory id}.


The @emph{@strong{file path}} of a file is the relative path to the file from the
root of the project tree.  It describes @emph{where} within a source tree a
file is located.


The @emph{@strong{inventory id}} of a file is a (mostly) arbitrary string that is
unique to the file within the tree.   The inventory id remains
constant even if a file is renamed.   So while the file path says
where a file is located, the inventory id says which file it is
that's stored at that path.


The purpose of @code{tla add} is to assign an inventory id to a file.


In our example, we can examine the ids:

@example
@group
        % tla inventory --source --ids
        hw.c    x_very_long_string
        main.c  x_another_very_long_string
        ^^^^    ^^^^^^^^^^^^^^^^^^^^^^^^^^
         |                |
         |           inventory ids
     file paths
@end group
@group
@end group
@end example

Ordinarily, when a file is moved, its file path changes, but its
inventory id should remain the same.  The @code{tla move} command 
helps with this.   Suppose that we:

@example
@group
        % mv hw.c hello.c
@end group
@group
@end group
@end example

@noindent
we should follow that with:

@example
@group
        % tla move hw.c hello.c
@end group
@group
@end group
@end example

@noindent
after which:

@example
@group
        % tla inventory --source --ids
        hello.c   x_very_long_string
        main.c    x_another_very_long_string
@end group
@group
@end group
@end example

Note that @code{hello.c} has the same inventory id that @code{hw.c} used to.


We'll come back to the topic of renames later so, for now, let's 
put things back where they started:

@example
@group
        % mv hello.c hw.c
        % tla move hello.c hw.c
@end group
@group
@end group
@end example



@need 3200

@section Quick Aside -- Adding Directories

The @code{tla add} command applies to directories, too.   If we were to
create a new subdirectory in the tree, we should @code{tla add} it:

@example
@group
        % mkdir docs
@end group
@group
@end group
@end example
@example
@group
        % tla inventory --names --source --both
        docs
        hw.c
        hello.c
@end group
@group
@end group
@end example

@noindent
but

@example
@group
        % tla inventory --source --both
        hw.c
        hello.c
@end group
@group
@end group
@end example

@noindent
unless

@example
@group
        % tla add docs
@end group
@group
@end group
@end example

@noindent
and then

@example
@group
        % tla inventory --source --both
        docs
        hw.c
        hello.c
@end group
@group
@end group
@end example

But again, for the sake of our example, we don't need docs.
We can just:

@example
@group
        % rm -rf docs
@end group
@group
@end group
@end example

There isn't a need to @code{tla delete} a directory that we physically remove.




@need 3200

@section How it Works -- tla add

What @code{tla add} does is fairly simple.   Note that when we added
@code{hw.c} and @code{main.c}, a new directory was created:

@example
@group
        % ls -a
        .               .arch-ids       hw.c.~1~        @{arch@}
        ..              hw.c            main.c
@end group
@group
@end group
@end example

The @code{.arch-ids} directory is new:

@example
@group
        % ls .arch-ids
        hw.c.id         main.c.id
@end group
@group
@end group
@end example
@example
@group
        % cat .arch-ids/hw.c.id
        very long string
@end group
@group
@end group
@end example

The @code{*.id} files is where the raw data that determines a file id are
stored.   The command @code{tla delete} removes those files.   The command
@code{tla move} renames them.


The id for a directory is stored slightly differently.  For example,
when we created a @code{docs} subdir and gave it an id with @code{tla add}, that
created a file @code{docs/.arch-ids/=id}.




@need 3200

@section Keeping Things Neat and Tidy

@geindex tree-lint



The command:

@example
@group
        % tla tree-lint
@end group
@group
@end group
@end example

@noindent
is useful for keeping things neat and tidy.


@code{tree-lint} will tell you of any ids for which the corresponding file
does not exist.  It will tell you of any files that pass the naming
conventions, but for which no explicit id exists.


It will also warn you about files that don't fit the naming
conventions.




@need 3200

@section Inventory Ids -- There's More Than One Way to Do It

In this chapter, you've learned about the basic commands @code{add},
@code{move}, and @code{delete}.   


The use of those tools for managing inventory ids was chosen as the
default behavior because, superficially at least, it resembles similar
commands in systems such as CVS which many users are already familiar
with.


There are other ways to manage inventory ids.   Sometimes the other
ways are more convenient.   A later chapter discusses these other
techniques (see: xref :@geindex !!!
@dfn{!!!}).




@need 3200

@section Why is it Like This -- The Purpose of Inventory Ids

As you'll see in later chapters, @code{arch} is good at managing @emph{changes}
made to source trees and the files they contain, and good at telling
you about the @emph{history} of trees and files.


As an example, let's suppose that Alice and Bob are both working on
the @code{hello_world} project.  In her tree, Alice makes some changes to
@code{hw.c}.  In his tree, Bob renames @code{hw.c} to @code{hello.c}.


At some point it is necessary to "sync-up" Alice and Bob.  Bob
should wind up with the changes Alice has been making.   Alice should
wind up with the same file renaming that Bob has done.


@code{arch} provides many mechanisms for that syncing up -- it's one of the
most important things that @code{arch} can do -- but nearly all of them
boil down to computing and applying @emph{@strong{changesets}}.


Alice can ask @code{arch} to create a changeset describing the work she's
done, and that changeset will describe the changes she made within
@code{hw.c}.  Bob can create a changeset and that changeset will describe
the file renaming he did.


If Alice applies Bob's changeset to her tree, her copy of @code{hw.c}
should be renamed @code{hello.c}.   But a trickier case is this:  What
happens if Bob applies Alice's changeset to his tree?


Alice changed a file named @code{./hw.c}, but in Bob's tree, those same
changes should be made to a file named @code{./hello.c}.  Fortunately, both
files have the same inventory id:

@example
@group

@end group
@group
        file path               inventory id
        ---------               -------------
@end group
@group

@end group
@group
                 Alice's tree:
        ./hw.c                  x_very_long_string
                                                  \ 
                                                   - the same long string
                 Bob's tree:                      /
        ./hello.c               x_very_long_string
@end group
@group

@end group
@end example

In Alice's changeset, the changes Alice made are described as being
made to the file whose id is @code{x_very_long_string}.


Therefore, when applying that changeset to Bob's tree, @code{arch} knows to
apply the changes to the file with that same id;  it knows to apply
the changes to his @code{./hello.c}.


That example illustrates what inventory ids are for: they allow
@code{arch} to describe the changes made to a tree in terms of the logical
identity of files rather than their physical location.  There are many
more complicated examples of how inventory ids come into play, but
now you've seen at least the basic point.




@need 3200

@section Why is it Like This -- Why tla move Doesn't Move Files

Why doesn't @code{tla delete} delete the file being removed from the source
category, or @code{tla move} rename it?


Those commands work as they do so that you can adjust the ids in a
tree even if some other tool which knows nothing about arch has
rearranged files.    For example, if you use a "directory editor" to
rename source files, @code{tla move} is available to catch-up to the
changes the directory editor made.


Sometimes, arch users request the addition of commands: @code{tla mv}, @code{tla
mkdir}, @code{tla rmdir}, and @code{tla rm} that would modify @emph{both} ids and
the corresponding source files.  That's a great idea and it's not all
that hard: so, if you're looking for something to do, that's a good
idea for a real-world programming project on which to try-out and
learn arch.  Let us know on the @code{gnu-arch-users} mailing list if you
do this, so that we can consider merging your changes into the
distribution.


@strong{Late Note:} One user recently contributed a @code{tla mv} command which
aims to be an inventory-id-aware replacement for @code{mv(1)}.







