Merge branch 'master' of .
authorJunio C Hamano <junkio@cox.net>
Mon, 12 Sep 2005 01:58:53 +0000 (18:58 -0700)
committerJunio C Hamano <junkio@cox.net>
Mon, 12 Sep 2005 01:58:53 +0000 (18:58 -0700)
Documentation/cvs-migration.txt
Documentation/diffcore.txt
Documentation/git-archimport.txt
Documentation/hooks.txt
Documentation/tutorial.txt
daemon.c
diff-helper.c
git-archimport.perl
read-cache.c

index 6e48bde..390a723 100644 (file)
@@ -186,7 +186,7 @@ you would use git-rev-list and git-diff-tree like this:
                nitfol();
        }'
 
-We have already talked about the "--stdin" form of git-diff-tree
+We have already talked about the "\--stdin" form of git-diff-tree
 command that reads the list of commits and compares each commit
 with its parents.  The git-whatchanged command internally runs
 the equivalent of the above command, and can be used like this:
index a0ffe85..1908b92 100644 (file)
@@ -22,8 +22,8 @@ The git-diff-* family works by first comparing two sets of
 files:
 
  - git-diff-index compares contents of a "tree" object and the
-   working directory (when '--cached' flag is not used) or a
-   "tree" object and the index file (when '--cached' flag is
+   working directory (when '\--cached' flag is not used) or a
+   "tree" object and the index file (when '\--cached' flag is
    used);
 
  - git-diff-files compares contents of the index file and the
@@ -164,11 +164,11 @@ similarity score different from the default 50% by giving a
 number after "-M" or "-C" option (e.g. "-M8" to tell it to use
 8/10 = 80%).
 
-Note.  When the "-C" option is used with --find-copies-harder
+Note.  When the "-C" option is used with `\--find-copies-harder`
 option, git-diff-\* commands feed unmodified filepairs to
 diffcore mechanism as well as modified ones.  This lets the copy
 detector consider unmodified files as copy source candidates at
-the expense of making it slower.  Without --find-copies-harder,
+the expense of making it slower.  Without `\--find-copies-harder`,
 git-diff-\* commands can detect copies only if the file that was
 copied happened to have been modified in the same changeset.
 
@@ -220,7 +220,7 @@ diffcore-pickaxe
 
 This transformation is used to find filepairs that represent
 changes that touch a specified string, and is controlled by the
--S option and the --pickaxe-all option to the git-diff-*
+-S option and the `\--pickaxe-all` option to the git-diff-*
 commands.
 
 When diffcore-pickaxe is in use, it checks if there are
@@ -229,9 +229,9 @@ whose "result" side does not.  Such a filepair represents "the
 string appeared in this changeset".  It also checks for the
 opposite case that loses the specified string.
 
-When --pickaxe-all is not in effect, diffcore-pickaxe leaves
+When `\--pickaxe-all` is not in effect, diffcore-pickaxe leaves
 only such filepairs that touches the specified string in its
-output.  When --pickaxe-all is used, diffcore-pickaxe leaves all
+output.  When `\--pickaxe-all` is used, diffcore-pickaxe leaves all
 filepairs intact if there is such a filepair, or makes the
 output empty otherwise.  The latter behaviour is designed to
 make reviewing of the changes in the context of the whole
index 8ce5f0a..fa0779b 100644 (file)
@@ -3,29 +3,69 @@ git-archimport(1)
 
 NAME
 ----
-git-archimport - Import an arch repository into git
+git-archimport - Import an Arch repository into GIT
 
 
 SYNOPSIS
 --------
-`git-archimport` [--option...] <args>
+`git-archimport` [ -h ] [ -v ] [ -T ] [ -t tempdir ] 
+                 <archive/branch> [ <archive/branch> ]
 
 DESCRIPTION
 -----------
-The script expects you to provide the key roots where it can start the
-import from an 'initial import' or 'tag' type of Arch commit. It will
-then follow all the branching and tagging within the provided roots.
+Imports a project from one or more Arch repositories. It will follow branches
+and repositories within the namespaces defined by the <archive/branch>
+parameters suppplied. If it cannot find the remote branch a merge comes from
+it will just import it as a regular commit. If it can find it, it will mark it 
+as a merge whenever possible (see discussion below). 
 
-It will die if it sees branches that have different roots.
+The script expects you to provide the key roots where it can start the import 
+from an 'initial import' or 'tag' type of Arch commit. It will follow and import 
+new branches within the provided roots. 
 
+It expects to be dealing with one project only. If it sees 
+branches that have different roots, it will refuse to run. In that case, edit your
+<archive/branch> parameters to define clearly the scope of the import. 
+
+`git-archimport` uses `tla` extensively in the background to access the Arch repository.
+Make sure you have a recent version of `tla` available in the path. `tla` must
+know about the repositories you pass to `git-archimport`. 
+
+For the initial import `git-archimport` expects to find itself in an empty 
+directory. To follow the development of a project that uses Arch, rerun 
+`git-archimport` with the same parameters as the initial import to perform incremental imports.
+
+MERGES
+------
+Patch merge data from Arch is used to mark merges in GIT as well. GIT 
+does not care much about tracking patches, and only considers a merge when a
+branch incorporates all the commits since the point they forked. The end result
+is that GIT will have a good idea of how far branches have diverged. So the 
+import process does lose some patch-trading metadata.
+
+Fortunately, when you try and merge branches imported from Arch, 
+GIT will find a good merge base, and it has a good chance of identifying 
+patches that have been traded out-of-sequence between the branches. 
 
 OPTIONS
 -------
---option::
-       Some option not yet documented.
 
-<args>...::
-       Some argument not yet documented.
+-h::
+       Display usage.
+
+-v::
+       Verbose output. 
+
+-T::
+       Many tags. Will create a tag for every commit, reflecting the commit 
+       name in the Arch repository.
+
+-t <tmpdir>::
+       Override the default tempdir.
+
+
+<archive/branch>::
+       Archive/branch identifier in a format that `tla log` understands. 
 
 
 Author
@@ -34,7 +74,7 @@ Written by Martin Langhoff <martin@catalyst.net.nz>.
 
 Documentation
 --------------
-Documentation by Junio C Hamano and the git-list <git@vger.kernel.org>.
+Documentation by Junio C Hamano, Martin Langhoff and the git-list <git@vger.kernel.org>.
 
 GIT
 ---
index ca0efee..57f4720 100644 (file)
@@ -57,7 +57,7 @@ pre-commit
 ----------
 
 This hook is invoked by `git-commit`, and can be bypassed
-with `--no-verify` option.  It takes no parameter, and is
+with `\--no-verify` option.  It takes no parameter, and is
 invoked before obtaining the proposed commit log message and
 making a commit.  Exiting with non-zero status from this script
 causes the `git-commit` to abort.
@@ -70,7 +70,7 @@ commit-msg
 ----------
 
 This hook is invoked by `git-commit`, and can be bypassed
-with `--no-verify` option.  It takes a single parameter, the
+with `\--no-verify` option.  It takes a single parameter, the
 name of the file that holds the proposed commit log message.
 Exiting with non-zero status causes the `git-commit` to
 abort.
index 6e100db..928a22c 100644 (file)
@@ -828,7 +828,7 @@ which will very loudly warn you that you're now committing a merge
 (which is correct, so never mind), and you can write a small merge
 message about your adventures in git-merge-land.
 
-After you're done, start up `gitk --all` to see graphically what the
+After you're done, start up `gitk \--all` to see graphically what the
 history looks like. Notice that `mybranch` still exists, and you can
 switch to it, and continue to work with it if you want to. The
 `mybranch` branch will not contain the merge, but next time you merge it
@@ -883,7 +883,7 @@ not actually do a merge. Instead, it just updated the top of
 the tree of your branch to that of the `master` branch. This is
 often called 'fast forward' merge.
 
-You can run `gitk --all` again to see how the commit ancestry
+You can run `gitk \--all` again to see how the commit ancestry
 looks like, or run `show-branch`, which tells you this.
 
 ------------------------------------------------
index 24bac16..5100cf2 100644 (file)
--- a/daemon.c
+++ b/daemon.c
@@ -80,11 +80,11 @@ static unsigned int children_deleted = 0;
 
 static struct child {
        pid_t pid;
-       socklen_t addrlen;
+       int addrlen;
        struct sockaddr_storage address;
 } live_child[MAX_CHILDREN];
 
-static void add_child(int idx, pid_t pid, struct sockaddr *addr, socklen_t addrlen)
+static void add_child(int idx, pid_t pid, struct sockaddr *addr, int addrlen)
 {
        live_child[idx].pid = pid;
        live_child[idx].addrlen = addrlen;
@@ -178,7 +178,7 @@ static void check_max_connections(void)
        }
 }
 
-static void handle(int incoming, struct sockaddr *addr, socklen_t addrlen)
+static void handle(int incoming, struct sockaddr *addr, int addrlen)
 {
        pid_t pid = fork();
 
@@ -308,7 +308,7 @@ static int serve(int port)
 
                        if (FD_ISSET(sockfd, &fds)) {
                                struct sockaddr_storage ss;
-                               socklen_t sslen = sizeof(ss);
+                               int sslen = sizeof(ss);
                                int incoming = accept(sockfd, (struct sockaddr *)&ss, &sslen);
                                if (incoming < 0) {
                                        switch (errno) {
index 3fa50ee..734956e 100644 (file)
@@ -91,7 +91,7 @@ int main(int ac, const char **av) {
                        if (*cp++ != ' ')
                                break;
                        status = *cp++;
-                       if (!strchr("MCRNDU", status))
+                       if (!strchr("AMCRDU", status))
                                break;
                        two_paths = score = 0;
                        if (status == DIFF_STATUS_RENAMED ||
index 06d8149..3749b8b 100755 (executable)
@@ -6,23 +6,25 @@
 # The basic idea is to walk the output of tla abrowse, 
 # fetch the changesets and apply them. 
 #
+
 =head1 Invocation
 
-    git-archimport -i <archive>/<branch> [<archive>/<branch>]
-    [ <archive>/<branch> ]
+    git-archimport [ -h ] [ -v ] [ -T ] [ -t tempdir ] <archive>/<branch> [ <archive>/<branch> ]
 
-    The script expects you to provide the key roots where it can start the
-    import from an 'initial import' or 'tag' type of Arch commit. It will
-    then follow all the branching and tagging within the provided roots.
+Imports a project from one or more Arch repositories. It will follow branches
+and repositories within the namespaces defined by the <archive/branch>
+parameters suppplied. If it cannot find the remote branch a merge comes from
+it will just import it as a regular commit. If it can find it, it will mark it 
+as a merge whenever possible.
 
-    It will die if it sees branches that have different roots. 
+See man (1) git-archimport for more details.
 
-=head2 TODO
+=head1 TODO
 
- - keep track of merged patches, and mark a git merge when it happens
- - smarter rules to parse the archive history "up" and "down"
- - be able to continue an import where we left off
+ - create tag objects instead of ref tags
  - audit shell-escaping of filenames
+ - hide our private tags somewhere smarter
+ - find a way to make "cat *patches | patch" safe even when patchfiles are missing newlines  
 
 =head1 Devel tricks
 
@@ -34,7 +36,7 @@ use strict;
 use warnings;
 use Getopt::Std;
 use File::Spec;
-use File::Temp qw(tempfile);
+use File::Temp qw(tempfile tempdir);
 use File::Path qw(mkpath);
 use File::Basename qw(basename dirname);
 use String::ShellQuote;
@@ -48,32 +50,31 @@ use IPC::Open2;
 $SIG{'PIPE'}="IGNORE";
 $ENV{'TZ'}="UTC";
 
+my $git_dir = $ENV{"GIT_DIR"} || ".git";
+$ENV{"GIT_DIR"} = $git_dir;
+
 our($opt_h,$opt_v, $opt_T,
     $opt_C,$opt_t);
 
 sub usage() {
     print STDERR <<END;
 Usage: ${\basename $0}     # fetch/update GIT from Arch
-       [ -h ] [ -v ] [ -T ] 
-       [ -C GIT_repository ] [ -t tempdir ] 
+       [ -h ] [ -v ] [ -T ] [ -t tempdir ] 
        repository/arch-branch [ repository/arch-branch] ...
 END
     exit(1);
 }
 
-getopts("ThviC:t:") or usage();
+getopts("Thvt:") or usage();
 usage if $opt_h;
 
 @ARGV >= 1 or usage();
 my @arch_roots = @ARGV;
 
-my $tmp = $opt_t;
-$tmp ||= '/tmp';
-$tmp .= '/git-archimport/';
-
-my $git_tree = $opt_C;
-$git_tree ||= ".";
-
+my ($tmpdir, $tmpdirname) = tempdir('git-archimport-XXXXXX', TMPDIR => 1, CLEANUP => 1);
+my $tmp = $opt_t || 1;
+$tmp = tempdir('git-archimport-XXXXXX', TMPDIR => 1, CLEANUP => 1);
+$opt_v && print "+ Using $tmp as temporary directory\n";
 
 my @psets  = ();                # the collection
 my %psets  = ();                # the collection, by name
@@ -180,7 +181,7 @@ foreach my $root (@arch_roots) {
 ##      and put an initial import
 ##      or a full tag
 my $import = 0;
-unless (-d '.git') { # initial import
+unless (-d $git_dir) { # initial import
     if ($psets[0]{type} eq 'i' || $psets[0]{type} eq 't') {
         print "Starting import from $psets[0]{id}\n";
        `git-init-db`;
@@ -191,11 +192,11 @@ unless (-d '.git') { # initial import
     }
 } else {    # progressing an import
     # load the rptags
-    opendir(DIR, ".git/archimport/tags")
+    opendir(DIR, "$git_dir/archimport/tags")
        || die "can't opendir: $!";
     while (my $file = readdir(DIR)) {
        # skip non-interesting-files
-       next unless -f ".git/archimport/tags/$file";
+       next unless -f "$git_dir/archimport/tags/$file";
        next if     $file =~ m/--base-0$/; # don't care for base-0
        my $sha = ptag($file);
        chomp $sha;
@@ -239,7 +240,7 @@ foreach my $ps (@psets) {
     }
 
     unless ($import) { # skip for import
-        if ( -e ".git/refs/heads/$ps->{branch}") {
+        if ( -e "$git_dir/refs/heads/$ps->{branch}") {
             # we know about this branch
             `git checkout    $ps->{branch}`;
         } else {
@@ -292,7 +293,7 @@ foreach my $ps (@psets) {
     # imports don't give us good info
     # on added files. Shame on them
     if ($ps->{type} eq 'i' || $ps->{type} eq 't') { 
-        `find . -type f -print0 | grep -zv '^./.git' | xargs -0 -l100 git-update-index --add`;
+        `find . -type f -print0 | grep -zv '^./$git_dir' | xargs -0 -l100 git-update-index --add`;
         `git-ls-files --deleted -z | xargs --no-run-if-empty -0 -l100 git-update-index --remove`;
     }
 
@@ -356,8 +357,8 @@ foreach my $ps (@psets) {
     # Who's your daddy?
     #
     my @par;
-    if ( -e ".git/refs/heads/$ps->{branch}") {
-        if (open HEAD, "<.git/refs/heads/$ps->{branch}") {
+    if ( -e "$git_dir/refs/heads/$ps->{branch}") {
+        if (open HEAD, "<$git_dir/refs/heads/$ps->{branch}") {
             my $p = <HEAD>;
             close HEAD;
             chomp $p;
@@ -404,11 +405,11 @@ foreach my $ps (@psets) {
     #
     # Update the branch
     # 
-    open  HEAD, ">.git/refs/heads/$ps->{branch}";
+    open  HEAD, ">$git_dir/refs/heads/$ps->{branch}";
     print HEAD $commitid;
     close HEAD;
-    unlink ('.git/HEAD');
-    symlink("refs/heads/$ps->{branch}",".git/HEAD");
+    unlink ("$git_dir/HEAD");
+    symlink("refs/heads/$ps->{branch}","$git_dir/HEAD");
 
     # tag accordingly
     ptag($ps->{id}, $commitid); # private tag
@@ -437,7 +438,7 @@ sub apply_import {
 
     `tla get -s --no-pristine -A $ps->{repo} $ps->{id} $tmp/import`;
     die "Cannot get import: $!" if $?;    
-    `rsync -v --archive --delete --exclude '.git' --exclude '.arch-ids' --exclude '{arch}' $tmp/import/* ./`;
+    `rsync -v --archive --delete --exclude '$git_dir' --exclude '.arch-ids' --exclude '{arch}' $tmp/import/* ./`;
     die "Cannot rsync import:$!" if $?;
     
     `rm -fr $tmp/import`;
@@ -483,7 +484,7 @@ sub apply_cset {
     }
 
     # bring in new files
-    `rsync --archive --exclude '.git' --exclude '.arch-ids' --exclude '{arch}' $tmp/changeset/new-files-archive/* ./`;
+    `rsync --archive --exclude '$git_dir' --exclude '.arch-ids' --exclude '{arch}' $tmp/changeset/new-files-archive/* ./`;
 
     # deleted files are hinted from the commitlog processing
 
@@ -578,7 +579,7 @@ sub tag {
     $tag = shell_quote($tag);
     
     if ($commit) {
-        open(C,">.git/refs/tags/$tag")
+        open(C,">$git_dir/refs/tags/$tag")
             or die "Cannot create tag $tag: $!\n";
         print C "$commit\n"
             or die "Cannot write tag $tag: $!\n";
@@ -586,7 +587,7 @@ sub tag {
             or die "Cannot write tag $tag: $!\n";
         print " * Created tag ' $tag' on '$commit'\n" if $opt_v;
     } else {                    # read
-        open(C,"<.git/refs/tags/$tag")
+        open(C,"<$git_dir/refs/tags/$tag")
             or die "Cannot read tag $tag: $!\n";
         $commit = <C>;
         chomp $commit;
@@ -604,12 +605,12 @@ sub ptag {
     $tag =~ s|/|--|g; 
     $tag = shell_quote($tag);
     
-    unless (-d '.git/archimport/tags') {
-        mkpath('.git/archimport/tags');
+    unless (-d "$git_dir/archimport/tags") {
+        mkpath("$git_dir/archimport/tags");
     }
 
     if ($commit) {              # write
-        open(C,">.git/archimport/tags/$tag")
+        open(C,">$git_dir/archimport/tags/$tag")
             or die "Cannot create tag $tag: $!\n";
         print C "$commit\n"
             or die "Cannot write tag $tag: $!\n";
@@ -619,10 +620,10 @@ sub ptag {
            unless $tag =~ m/--base-0$/;
     } else {                    # read
         # if the tag isn't there, return 0
-        unless ( -s ".git/archimport/tags/$tag") {
+        unless ( -s "$git_dir/archimport/tags/$tag") {
             return 0;
         }
-        open(C,"<.git/archimport/tags/$tag")
+        open(C,"<$git_dir/archimport/tags/$tag")
             or die "Cannot read tag $tag: $!\n";
         $commit = <C>;
         chomp $commit;
index ced5973..6eff4c8 100644 (file)
@@ -462,6 +462,13 @@ static int ce_flush(SHA_CTX *context, int fd)
                SHA1_Update(context, write_buffer, left);
        }
 
+       /* Flush first if not enough space for SHA1 signature */
+       if (left + 20 > WRITE_BUFFER_SIZE) {
+               if (write(fd, write_buffer, left) != left)
+                       return -1;
+               left = 0;
+       }
+
        /* Append the SHA1 signature at the end */
        SHA1_Final(write_buffer + left, context);
        left += 20;