Merge branch 'jc/checkout'
authorJunio C Hamano <junkio@cox.net>
Mon, 26 Dec 2005 07:30:15 +0000 (23:30 -0800)
committerJunio C Hamano <junkio@cox.net>
Mon, 26 Dec 2005 07:30:15 +0000 (23:30 -0800)
13 files changed:
Documentation/git-ls-files.txt
Documentation/tutorial.txt
cache.h
debian/changelog
environment.c
git-clone.sh
git-merge.sh
init-db.c
ls-files.c
mailinfo.c
setup.c
sha1_file.c
show-branch.c
index 2f308ecda9d039224d2714e4cfd209422605430f..186f3bb57a6d77da9705860d730cf8cd3c9d867f 100644 (file)
@@ -13,7 +13,8 @@ SYNOPSIS
                (-[c|d|o|i|s|u|k|m])\*
                [-x <pattern>|--exclude=<pattern>]
                [-X <file>|--exclude-from=<file>]
-               [--exclude-per-directory=<file>] [--] [<file>]\*
+               [--exclude-per-directory=<file>] 
+               [--full-name] [--] [<file>]\*
 
 DESCRIPTION
 -----------
@@ -77,6 +78,12 @@ OPTIONS
        K::     to be killed
        ?       other
 
+--full-name::
+       When run from a subdirectory, the command usually
+       outputs paths relative to the current directory.  This
+       option forces paths to be output relative to the project
+       top directory.
+
 --::
        Do not interpret any more arguments as options.
 
index 3a5c56e24edfe7a970e6dcd346f8c0a346cdbfd8..edd91cbbe42bec1ee406dd95d82832575d89d3a6 100644 (file)
@@ -1695,6 +1695,24 @@ You still need to create UNIX user accounts for each developer,
 and put them in the same group.  Make sure that the repository
 shared among these developers is writable by that group.
 
+. Initializing the shared repository with `git-init-db --shared`
+helps somewhat.
+
+. Run the following in the shared repository:
++
+------------
+$ chgrp -R $group repo.git
+$ find repo.git -type d -print | xargs chmod ug+rwx,g+s
+$ GIT_DIR=repo.git git repo-config core.sharedrepository true
+------------
+
+The above measures make sure that directories lazily created in
+`$GIT_DIR` are writable by group members.  You, as the
+repository administrator, are still responsible to make sure
+your developers belong to that shared repository group and set
+their umask to a value no stricter than 027 (i.e. at least allow
+reading and searching by group members).
+
 You can implement finer grained branch policies using update
 hooks.  There is a document ("control access to branches") in
 Documentation/howto by Carl Baldwin and JC outlining how to (1)
diff --git a/cache.h b/cache.h
index cb87becb3aaea75915a65e99565c418d6765174b..a99fb3ce7d3423d51f5a0829a4bd20f0cd5ca0e1 100644 (file)
--- a/cache.h
+++ b/cache.h
@@ -159,6 +159,7 @@ extern void rollback_index_file(struct cache_file *);
 extern int trust_executable_bit;
 extern int only_use_symrefs;
 extern int diff_rename_limit_default;
+extern int shared_repository;
 
 #define GIT_REPO_VERSION 0
 extern int repository_format_version;
@@ -183,6 +184,7 @@ extern const unsigned char null_sha1[20];
 
 int git_mkstemp(char *path, size_t n, const char *template);
 
+int adjust_shared_perm(const char *path);
 int safe_create_leading_directories(char *path);
 char *safe_strncpy(char *, const char *, size_t);
 char *enter_repo(char *path, int strict);
index 8d6c0667c7dc9c8ef92ba494d0ddc625e0f01260..d7f75910798c14e21107c26c97f76292fb3c62a9 100644 (file)
@@ -10,6 +10,12 @@ git-core (1.0.0.GIT-0) unstable; urgency=low
 
  -- Junio C Hamano <junkio@cox.net>  Wed, 21 Dec 2005 12:12:05 -0800
 
+git-core (1.0.4-0) unstable; urgency=low
+
+  * GIT 1.0.4.
+
+ -- Junio C Hamano <junkio@cox.net>  Sat, 24 Dec 2005 00:01:20 -0800
+
 git-core (1.0.3-0) unstable; urgency=low
 
   * GIT 1.0.3 maintenance release.
index 0886ad38f94ddb897629d832160333921ac89481..0596fc647be37343371ae5a266906dab35707076 100644 (file)
@@ -15,6 +15,7 @@ int trust_executable_bit = 1;
 int only_use_symrefs = 0;
 int repository_format_version = 0;
 char git_commit_encoding[MAX_ENCODING_LENGTH] = "utf-8";
+int shared_repository = 0;
 
 static char *git_dir, *git_object_dir, *git_index_file, *git_refs_dir,
        *git_graft_file;
index bfc6c2d79ff3d6c50fd397c36ee04693695ad814..377d59e62cecd305fc7cf69aa927b13225fdb3eb 100755 (executable)
@@ -31,25 +31,11 @@ clone_dumb_http () {
        cd "$2" &&
        clone_tmp='.git/clone-tmp' &&
        mkdir -p "$clone_tmp" || exit 1
-       http_fetch "$1/info/refs" "$clone_tmp/refs" &&
-       http_fetch "$1/objects/info/packs" "$clone_tmp/packs" || {
+       http_fetch "$1/info/refs" "$clone_tmp/refs" || {
                echo >&2 "Cannot get remote repository information.
 Perhaps git-update-server-info needs to be run there?"
                exit 1;
        }
-       while read type name
-       do
-               case "$type" in
-               P) ;;
-               *) continue ;;
-               esac &&
-
-               idx=`expr "$name" : '\(.*\)\.pack'`.idx
-               http_fetch "$1/objects/pack/$name" ".git/objects/pack/$name" &&
-               http_fetch "$1/objects/pack/$idx" ".git/objects/pack/$idx" &&
-               git-verify-pack ".git/objects/pack/$idx" || exit 1
-       done <"$clone_tmp/packs"
-
        while read sha1 refname
        do
                name=`expr "$refname" : 'refs/\(.*\)'` &&
index e50fbb1160ad6ccfebc0d65fcc54bc3488e597cd..0a158ef779eb8717f27e632e31726f00586979ed 100755 (executable)
@@ -209,6 +209,7 @@ case "$use_strategies" in
 esac
 
 result_tree= best_cnt=-1 best_strategy= wt_strategy=
+merge_was_ok=
 for strategy in $use_strategies
 do
     test "$wt_strategy" = '' || {
@@ -228,6 +229,7 @@ do
     exit=$?
     if test "$no_commit" = t && test "$exit" = 0
     then
+        merge_was_ok=t
        exit=1 ;# pretend it left conflicts.
     fi
 
@@ -293,4 +295,11 @@ do
 done >"$GIT_DIR/MERGE_HEAD"
 echo $merge_msg >"$GIT_DIR/MERGE_MSG"
 
-die "Automatic merge failed/prevented; fix up by hand"
+if test "$merge_was_ok" = t
+then
+       echo >&2 \
+       "Automatic merge went well; stopped before committing as requested"
+       exit 0
+else
+       die "Automatic merge failed; fix up by hand"
+fi
index ead37b5ed86e5ae96c18d081fbfffd65ed74dce8..ff294960f29c8763e34e28060dee04b799bd55fd 100644 (file)
--- a/init-db.c
+++ b/init-db.c
@@ -9,7 +9,7 @@
 #define DEFAULT_GIT_TEMPLATE_DIR "/usr/share/git-core/templates/"
 #endif
 
-static void safe_create_dir(const char *dir)
+static void safe_create_dir(const char *dir, int share)
 {
        if (mkdir(dir, 0777) < 0) {
                if (errno != EEXIST) {
@@ -17,6 +17,8 @@ static void safe_create_dir(const char *dir)
                        exit(1);
                }
        }
+       else if (share && adjust_shared_perm(dir))
+               die("Could not make %s writable by group\n", dir);
 }
 
 static int copy_file(const char *dst, const char *src, int mode)
@@ -32,6 +34,10 @@ static int copy_file(const char *dst, const char *src, int mode)
        }
        status = copy_fd(fdi, fdo);
        close(fdo);
+
+       if (!status && adjust_shared_perm(dst))
+               return -1;
+
        return status;
 }
 
@@ -48,7 +54,7 @@ static void copy_templates_1(char *path, int baselen,
         * with the way the namespace under .git/ is organized, should
         * be really carefully chosen.
         */
-       safe_create_dir(path);
+       safe_create_dir(path, 1);
        while ((de = readdir(dir)) != NULL) {
                struct stat st_git, st_template;
                int namelen;
@@ -176,11 +182,11 @@ static void create_default_files(const char *git_dir, char *template_path)
         * Create .git/refs/{heads,tags}
         */
        strcpy(path + len, "refs");
-       safe_create_dir(path);
+       safe_create_dir(path, 1);
        strcpy(path + len, "refs/heads");
-       safe_create_dir(path);
+       safe_create_dir(path, 1);
        strcpy(path + len, "refs/tags");
-       safe_create_dir(path);
+       safe_create_dir(path, 1);
 
        /* First copy the templates -- we might have the default
         * config file there, in which case we would want to read
@@ -220,7 +226,7 @@ static void create_default_files(const char *git_dir, char *template_path)
 }
 
 static const char init_db_usage[] =
-"git-init-db [--template=<template-directory>]";
+"git-init-db [--template=<template-directory>] [--shared]";
 
 /*
  * If you want to, you can share the DB area with any number of branches.
@@ -239,6 +245,8 @@ int main(int argc, char **argv)
                char *arg = argv[1];
                if (!strncmp(arg, "--template=", 11))
                        template_dir = arg+11;
+               else if (!strcmp(arg, "--shared"))
+                       shared_repository = 1;
                else
                        die(init_db_usage);
        }
@@ -251,7 +259,7 @@ int main(int argc, char **argv)
                git_dir = DEFAULT_GIT_DIR_ENVIRONMENT;
                fprintf(stderr, "defaulting to local storage area\n");
        }
-       safe_create_dir(git_dir);
+       safe_create_dir(git_dir, 0);
 
        /* Check to see if the repository version is right.
         * Note that a newly created repository does not have
@@ -270,10 +278,14 @@ int main(int argc, char **argv)
        path = xmalloc(len + 40);
        memcpy(path, sha1_dir, len);
 
-       safe_create_dir(sha1_dir);
+       safe_create_dir(sha1_dir, 1);
        strcpy(path+len, "/pack");
-       safe_create_dir(path);
+       safe_create_dir(path, 1);
        strcpy(path+len, "/info");
-       safe_create_dir(path);
+       safe_create_dir(path, 1);
+
+       if (shared_repository)
+               git_config_set("core.sharedRepository", "true");
+
        return 0;
 }
index f3f1a6a6633881bf43887731fdcbe08af9ad2f4a..5e9ac712af069e773fd7dd562706384b45683753 100644 (file)
@@ -562,7 +562,7 @@ static void verify_pathspec(void)
 static const char ls_files_usage[] =
        "git-ls-files [-z] [-t] (--[cached|deleted|others|stage|unmerged|killed|modified])* "
        "[ --ignored ] [--exclude=<pattern>] [--exclude-from=<file>] "
-       "[ --exclude-per-directory=<filename> ] [--] [<file>]*";
+       "[ --exclude-per-directory=<filename> ] [--full-name] [--] [<file>]*";
 
 int main(int argc, const char **argv)
 {
index 9f95f37651e2ce5a3930051fe875f1c16ede97c2..0265a29a3855902e25e44099663c2973bbe9f53e 100644 (file)
@@ -472,7 +472,7 @@ static void convert_to_utf8(char *line, char *charset)
        char *in, *out;
        size_t insize, outsize, nrc;
        char outbuf[4096]; /* cheat */
-       static char latin_one[] = "latin-1";
+       static char latin_one[] = "latin1";
        char *input_charset = *charset ? charset : latin_one;
        iconv_t conv = iconv_open(metainfo_charset, input_charset);
 
diff --git a/setup.c b/setup.c
index d3556edf121ba78b0b83d20fdbd9cb397e79eb2b..36ede3d87483548bb1ce6c19361d7f6584386147 100644 (file)
--- a/setup.c
+++ b/setup.c
@@ -180,6 +180,8 @@ int check_repository_format_version(const char *var, const char *value)
 {
        if (strcmp(var, "core.repositoryformatversion") == 0)
                repository_format_version = git_config_int(var, value);
+       else if (strcmp(var, "core.sharedrepository") == 0)
+               shared_repository = git_config_bool(var, value);
        return 0;
 }
 
index 6b7577dbc4ed845da1a70b6d727370423b086735..8bebbb255f762fc36f165b87023d8cc37732968a 100644 (file)
@@ -48,6 +48,29 @@ int get_sha1_hex(const char *hex, unsigned char *sha1)
        return 0;
 }
 
+int adjust_shared_perm(const char *path)
+{
+       struct stat st;
+       int mode;
+
+       if (!shared_repository)
+               return 0;
+       if (lstat(path, &st) < 0)
+               return -1;
+       mode = st.st_mode;
+       if (mode & S_IRUSR)
+               mode |= S_IRGRP;
+       if (mode & S_IWUSR)
+               mode |= S_IWGRP;
+       if (mode & S_IXUSR)
+               mode |= S_IXGRP;
+       if (S_ISDIR(mode))
+               mode |= S_ISGID;
+       if (chmod(path, mode) < 0)
+               return -2;
+       return 0;
+}
+
 int safe_create_leading_directories(char *path)
 {
        char *pos = path;
@@ -59,11 +82,16 @@ int safe_create_leading_directories(char *path)
                if (!pos)
                        break;
                *pos = 0;
-               if (mkdir(path, 0777) < 0)
+               if (mkdir(path, 0777) < 0) {
                        if (errno != EEXIST) {
                                *pos = '/';
                                return -1;
                        }
+               }
+               else if (adjust_shared_perm(path)) {
+                       *pos = '/';
+                       return -2;
+               }
                *pos++ = '/';
        }
        return 0;
@@ -1255,6 +1283,8 @@ static int link_temp_to_file(const char *tmpfile, char *filename)
                if (dir) {
                        *dir = 0;
                        mkdir(filename, 0777);
+                       if (adjust_shared_perm(filename))
+                               return -2;
                        *dir = '/';
                        if (!link(tmpfile, filename))
                                return 0;
index 3fe62b7177241aaf0512b586e2dfe862d3b66b9c..15b1968781178c8aa939a79ed5a7f8fb363d181e 100644 (file)
@@ -284,10 +284,54 @@ static void show_one_commit(struct commit *commit, int no_name)
 static char *ref_name[MAX_REVS + 1];
 static int ref_name_cnt;
 
+static const char *find_digit_prefix(const char *s, int *v)
+{
+       const char *p;
+       int ver;
+       char ch;
+
+       for (p = s, ver = 0;
+            '0' <= (ch = *p) && ch <= '9';
+            p++)
+               ver = ver * 10 + ch - '0';
+       *v = ver;
+       return p;
+}
+
+
+static int version_cmp(const char *a, const char *b)
+{
+       while (1) {
+               int va, vb;
+
+               a = find_digit_prefix(a, &va);
+               b = find_digit_prefix(b, &vb);
+               if (va != vb)
+                       return va - vb;
+
+               while (1) {
+                       int ca = *a;
+                       int cb = *b;
+                       if ('0' <= ca && ca <= '9')
+                               ca = 0;
+                       if ('0' <= cb && cb <= '9')
+                               cb = 0;
+                       if (ca != cb)
+                               return ca - cb;
+                       if (!ca)
+                               break;
+                       a++;
+                       b++;
+               }
+               if (!*a && !*b)
+                       return 0;
+       }
+}
+
 static int compare_ref_name(const void *a_, const void *b_)
 {
        const char * const*a = a_, * const*b = b_;
-       return strcmp(*a, *b);
+       return version_cmp(*a, *b);
 }
 
 static void sort_ref_range(int bottom, int top)
@@ -299,8 +343,15 @@ static void sort_ref_range(int bottom, int top)
 static int append_ref(const char *refname, const unsigned char *sha1)
 {
        struct commit *commit = lookup_commit_reference_gently(sha1, 1);
+       int i;
+
        if (!commit)
                return 0;
+       /* Avoid adding the same thing twice */
+       for (i = 0; i < ref_name_cnt; i++)
+               if (!strcmp(refname, ref_name[i]))
+                       return 0;
+
        if (MAX_REVS <= ref_name_cnt) {
                fprintf(stderr, "warning: ignoring %s; "
                        "cannot handle more than %d refs\n",
@@ -512,19 +563,17 @@ int main(int ac, char **av)
        if (1 < independent + merge_base + (extra != 0))
                usage(show_branch_usage);
 
+       /* If nothing is specified, show all branches by default */
+       if (ac + all_heads + all_tags == 0)
+               all_heads = 1;
+
        if (all_heads + all_tags)
                snarf_refs(all_heads, all_tags);
-
-       if (ac) {
-               while (0 < ac) {
-                       append_one_rev(*av);
-                       ac--; av++;
-               }
-       }
-       else {
-               /* If no revs given, then add heads */
-               snarf_refs(1, 0);
+       while (0 < ac) {
+               append_one_rev(*av);
+               ac--; av++;
        }
+
        if (!ref_name_cnt) {
                fprintf(stderr, "No revs to be shown.\n");
                exit(0);