Merge branch 'cr/tag'
authorJunio C Hamano <gitster@pobox.com>
Sat, 11 Aug 2007 06:17:46 +0000 (23:17 -0700)
committerJunio C Hamano <gitster@pobox.com>
Sat, 11 Aug 2007 06:17:46 +0000 (23:17 -0700)
* cr/tag:
Teach "git stripspace" the --strip-comments option
Make verify-tag a builtin.
builtin-tag.c: Fix two memory leaks and minor notation changes.
launch_editor(): Heed GIT_EDITOR and core.editor settings
Make git tag a builtin.

1  2 
Makefile
cache.h
config.c
environment.c
git.c
diff --combined Makefile
index b685c7e39ef56513714c8b723f9fef055271780c,98670bbd716ba55aff15ae2b4f7afea61c04df7c..4eb463797adc693dc168b926b6932ff53f17d0b1
+++ b/Makefile
@@@ -151,7 -151,6 +151,7 @@@ sysconfdir = /et
  else
  sysconfdir = $(prefix)/etc
  endif
 +lib = lib
  ETC_GITCONFIG = $(sysconfdir)/gitconfig
  # DESTDIR=
  
@@@ -177,7 -176,6 +177,7 @@@ CC = gc
  AR = ar
  RM = rm -f
  TAR = tar
 +FIND = find
  INSTALL = install
  RPMBUILD = rpmbuild
  TCL_PATH = tclsh
@@@ -208,7 -206,6 +208,6 @@@ SCRIPT_SH = 
        git-pull.sh git-rebase.sh git-rebase--interactive.sh \
        git-repack.sh git-request-pull.sh git-reset.sh \
        git-sh-setup.sh \
-       git-tag.sh git-verify-tag.sh \
        git-am.sh \
        git-merge.sh git-merge-stupid.sh git-merge-octopus.sh \
        git-merge-resolve.sh git-merge-ours.sh \
@@@ -363,18 -360,20 +362,20 @@@ BUILTIN_OBJS = 
        builtin-show-branch.o \
        builtin-stripspace.o \
        builtin-symbolic-ref.o \
+       builtin-tag.o \
        builtin-tar-tree.o \
        builtin-unpack-objects.o \
        builtin-update-index.o \
        builtin-update-ref.o \
        builtin-upload-archive.o \
        builtin-verify-pack.o \
+       builtin-verify-tag.o \
        builtin-write-tree.o \
        builtin-show-ref.o \
        builtin-pack-refs.o
  
  GITLIBS = $(LIB_FILE) $(XDIFF_LIB)
 -EXTLIBS = -lz
 +EXTLIBS =
  
  #
  # Platform specific tweaks
@@@ -458,10 -457,6 +459,10 @@@ ifeq ($(uname_S),AIX
        NO_STRLCPY = YesPlease
        NEEDS_LIBICONV=YesPlease
  endif
 +ifeq ($(uname_S),GNU)
 +      # GNU/Hurd
 +      NO_STRLCPY=YesPlease
 +endif
  ifeq ($(uname_S),IRIX64)
        NO_IPV6=YesPlease
        NO_SETENV=YesPlease
@@@ -505,9 -500,9 +506,9 @@@ endi
  
  ifndef NO_CURL
        ifdef CURLDIR
 -              # Try "-Wl,-rpath=$(CURLDIR)/lib" in such a case.
 +              # Try "-Wl,-rpath=$(CURLDIR)/$(lib)" in such a case.
                BASIC_CFLAGS += -I$(CURLDIR)/include
 -              CURL_LIBCURL = -L$(CURLDIR)/lib $(CC_LD_DYNPATH)$(CURLDIR)/lib -lcurl
 +              CURL_LIBCURL = -L$(CURLDIR)/$(lib) $(CC_LD_DYNPATH)$(CURLDIR)/$(lib) -lcurl
        else
                CURL_LIBCURL = -lcurl
        endif
        endif
  endif
  
 +ifdef ZLIB_PATH
 +      BASIC_CFLAGS += -I$(ZLIB_PATH)/include
 +      EXTLIBS += -L$(ZLIB_PATH)/$(lib) $(CC_LD_DYNPATH)$(ZLIB_PATH)/$(lib)
 +endif
 +EXTLIBS += -lz
 +
  ifndef NO_OPENSSL
        OPENSSL_LIBSSL = -lssl
        ifdef OPENSSLDIR
                BASIC_CFLAGS += -I$(OPENSSLDIR)/include
 -              OPENSSL_LINK = -L$(OPENSSLDIR)/lib $(CC_LD_DYNPATH)$(OPENSSLDIR)/lib
 +              OPENSSL_LINK = -L$(OPENSSLDIR)/$(lib) $(CC_LD_DYNPATH)$(OPENSSLDIR)/$(lib)
        else
                OPENSSL_LINK =
        endif
@@@ -550,7 -539,7 +551,7 @@@ endi
  ifdef NEEDS_LIBICONV
        ifdef ICONVDIR
                BASIC_CFLAGS += -I$(ICONVDIR)/include
 -              ICONV_LINK = -L$(ICONVDIR)/lib $(CC_LD_DYNPATH)$(ICONVDIR)/lib
 +              ICONV_LINK = -L$(ICONVDIR)/$(lib) $(CC_LD_DYNPATH)$(ICONVDIR)/$(lib)
        else
                ICONV_LINK =
        endif
@@@ -913,16 -902,13 +914,16 @@@ perl/Makefile: perl/Git.pm perl/Makefil
  doc:
        $(MAKE) -C Documentation all
  
 +info:
 +      $(MAKE) -C Documentation info
 +
  TAGS:
        $(RM) TAGS
 -      find . -name '*.[hcS]' -print | xargs etags -a
 +      $(FIND) . -name '*.[hcS]' -print | xargs etags -a
  
  tags:
        $(RM) tags
 -      find . -name '*.[hcS]' -print | xargs ctags -a
 +      $(FIND) . -name '*.[hcS]' -print | xargs ctags -a
  
  ### Detect prefix changes
  TRACK_CFLAGS = $(subst ','\'',$(ALL_CFLAGS)):\
@@@ -951,7 -937,7 +952,7 @@@ endi
  
  ### Testing rules
  
 -TEST_PROGRAMS = test-chmtime$X test-genrandom$X test-date$X test-delta$X test-sha1$X test-match-trees$X
 +TEST_PROGRAMS = test-chmtime$X test-genrandom$X test-date$X test-delta$X test-sha1$X test-match-trees$X test-absolute-path$X
  
  all:: $(TEST_PROGRAMS)
  
@@@ -1008,9 -994,6 +1009,9 @@@ endi
  install-doc:
        $(MAKE) -C Documentation install
  
 +install-info:
 +      $(MAKE) -C Documentation install-info
 +
  quick-install-doc:
        $(MAKE) -C Documentation quick-install
  
diff --combined cache.h
index e5276e6add08ba5db43768cf103caaef1bd06b77,67b1af16d9f06a76ed9616df9c96ce4b1f839bd4..4507404240e404cac040a9435a29eb85a879a03d
+++ b/cache.h
@@@ -208,15 -208,12 +208,15 @@@ enum object_type 
  extern int is_bare_repository_cfg;
  extern int is_bare_repository(void);
  extern int is_inside_git_dir(void);
 +extern char *git_work_tree_cfg;
  extern int is_inside_work_tree(void);
  extern const char *get_git_dir(void);
  extern char *get_object_directory(void);
  extern char *get_refs_directory(void);
  extern char *get_index_file(void);
  extern char *get_graft_file(void);
 +extern int set_git_dir(const char *path);
 +extern const char *get_git_work_tree(void);
  
  #define ALTERNATE_DB_ENVIRONMENT "GIT_ALTERNATE_OBJECT_DIRECTORIES"
  
@@@ -258,7 -255,6 +258,7 @@@ extern int index_name_pos(struct index_
  #define ADD_CACHE_OK_TO_ADD 1         /* Ok to add */
  #define ADD_CACHE_OK_TO_REPLACE 2     /* Ok to replace file/directory */
  #define ADD_CACHE_SKIP_DFCHECK 4      /* Ok to skip DF conflict checks */
 +#define ADD_CACHE_JUST_APPEND 8               /* Append only; tree.c::read_tree() */
  extern int add_index_entry(struct index_state *, struct cache_entry *ce, int option);
  extern struct cache_entry *refresh_cache_entry(struct cache_entry *ce, int really);
  extern int remove_index_entry_at(struct index_state *, int pos);
@@@ -362,11 -358,6 +362,11 @@@ int git_config_perm(const char *var, co
  int adjust_shared_perm(const char *path);
  int safe_create_leading_directories(char *path);
  char *enter_repo(char *path, int strict);
 +static inline int is_absolute_path(const char *path)
 +{
 +      return path[0] == '/';
 +}
 +const char *make_absolute_path(const char *path);
  
  /* Read and unpack a sha1 file into memory, write memory to a sha1 file */
  extern int sha1_object_info(const unsigned char *, unsigned long *);
@@@ -569,6 -560,8 +569,8 @@@ extern char *pager_program
  extern int pager_in_use;
  extern int pager_use_color;
  
+ extern char *editor_program;
  /* base85 */
  int decode_85(char *dst, const char *line, int linelen);
  void encode_85(char *buf, const unsigned char *data, int bytes);
diff --combined config.c
index dd2de6e38e8d68d8622ad542e5c73cbcffeceeac,103b4fcc61192d18c63b198a5eb37bbdf154a6b0..dc3148d4566205858869973804de1c2ddb19e981
+++ b/config.c
@@@ -426,6 -426,11 +426,11 @@@ int git_default_config(const char *var
                return 0;
        }
  
+       if (!strcmp(var, "core.editor")) {
+               editor_program = xstrdup(value);
+               return 0;
+       }
        /* Add other config variables here and to Documentation/config.txt. */
        return 0;
  }
@@@ -715,7 -720,7 +720,7 @@@ int git_config_set_multivar(const char
        int fd = -1, in_fd;
        int ret;
        char* config_filename;
 -      char* lock_file;
 +      struct lock_file *lock = NULL;
        const char* last_dot = strrchr(key, '.');
  
        config_filename = getenv(CONFIG_ENVIRONMENT);
                        config_filename  = git_path("config");
        }
        config_filename = xstrdup(config_filename);
 -      lock_file = xstrdup(mkpath("%s.lock", config_filename));
  
        /*
         * Since "key" actually contains the section name and the real
        store.key[i] = 0;
  
        /*
 -       * The lock_file serves a purpose in addition to locking: the new
 +       * The lock serves a purpose in addition to locking: the new
         * contents of .git/config will be written into it.
         */
 -      fd = open(lock_file, O_WRONLY | O_CREAT | O_EXCL, 0666);
 -      if (fd < 0 || adjust_shared_perm(lock_file)) {
 +      lock = xcalloc(sizeof(struct lock_file), 1);
 +      fd = hold_lock_file_for_update(lock, config_filename, 0);
 +      if (fd < 0) {
                fprintf(stderr, "could not lock config file\n");
                free(store.key);
                ret = -1;
                                goto write_err_out;
  
                munmap(contents, contents_sz);
 -              unlink(config_filename);
        }
  
 -      if (rename(lock_file, config_filename) < 0) {
 -              fprintf(stderr, "Could not rename the lock file?\n");
 +      if (close(fd) || commit_lock_file(lock) < 0) {
 +              fprintf(stderr, "Cannot commit config file!\n");
                ret = 4;
                goto out_free;
        }
  
 +      /* fd is closed, so don't try to close it below. */
 +      fd = -1;
 +      /*
 +       * lock is committed, so don't try to roll it back below.
 +       * NOTE: Since lockfile.c keeps a linked list of all created
 +       * lock_file structures, it isn't safe to free(lock).  It's
 +       * better to just leave it hanging around.
 +       */
 +      lock = NULL;
        ret = 0;
  
  out_free:
        if (0 <= fd)
                close(fd);
 +      if (lock)
 +              rollback_lock_file(lock);
        free(config_filename);
 -      if (lock_file) {
 -              unlink(lock_file);
 -              free(lock_file);
 -      }
        return ret;
  
  write_err_out:
diff --combined environment.c
index 2af12fd68968c5b6ceab645fd0142f4f30a6f87a,35d3f4b595872c39c640ca0f71e7846d3ad053f2..b5a6c69f7c1d214daa2556d04dd35e0976fc6e5e
@@@ -33,12 -33,9 +33,13 @@@ size_t delta_base_cache_limit = 16 * 10
  char *pager_program;
  int pager_in_use;
  int pager_use_color = 1;
+ char *editor_program;
  int auto_crlf = 0;    /* 1: both ways, -1: only when adding git objects */
  
 +/* This is set by setup_git_dir_gently() and/or git_default_config() */
 +char *git_work_tree_cfg;
 +static const char *work_tree;
 +
  static const char *git_dir;
  static char *git_object_dir, *git_index_file, *git_refs_dir, *git_graft_file;
  
@@@ -66,8 -63,15 +67,8 @@@ static void setup_git_env(void
  
  int is_bare_repository(void)
  {
 -      const char *dir, *s;
 -      if (0 <= is_bare_repository_cfg)
 -              return is_bare_repository_cfg;
 -
 -      dir = get_git_dir();
 -      if (!strcmp(dir, DEFAULT_GIT_DIR_ENVIRONMENT))
 -              return 0;
 -      s = strrchr(dir, '/');
 -      return !s || strcmp(s + 1, DEFAULT_GIT_DIR_ENVIRONMENT);
 +      /* if core.bare is not 'false', let's see if there is a work tree */
 +      return is_bare_repository_cfg && !get_git_work_tree();
  }
  
  const char *get_git_dir(void)
        return git_dir;
  }
  
 +const char *get_git_work_tree(void)
 +{
 +      static int initialized = 0;
 +      if (!initialized) {
 +              work_tree = getenv(GIT_WORK_TREE_ENVIRONMENT);
 +              /* core.bare = true overrides implicit and config work tree */
 +              if (!work_tree && is_bare_repository_cfg < 1) {
 +                      work_tree = git_work_tree_cfg;
 +                      /* make_absolute_path also normalizes the path */
 +                      if (work_tree && !is_absolute_path(work_tree))
 +                              work_tree = xstrdup(make_absolute_path(git_path(work_tree)));
 +              } else if (work_tree)
 +                      work_tree = xstrdup(make_absolute_path(work_tree));
 +              initialized = 1;
 +              if (work_tree)
 +                      is_bare_repository_cfg = 0;
 +      }
 +      return work_tree;
 +}
 +
  char *get_object_directory(void)
  {
        if (!git_object_dir)
@@@ -124,11 -108,3 +125,11 @@@ char *get_graft_file(void
                setup_git_env();
        return git_graft_file;
  }
 +
 +int set_git_dir(const char *path)
 +{
 +      if (setenv(GIT_DIR_ENVIRONMENT, path, 1))
 +              return error("Could not set GIT_DIR to '%s'", path);
 +      setup_git_env();
 +      return 0;
 +}
diff --combined git.c
index f8c4545208472acfbb73ce527a134979ea97db43,230e50611f5946c416882734af5b1b838c3ef50c..e5daae0f95d33dd19e7c02a50b7addfd59c64058
--- 1/git.c
--- 2/git.c
+++ b/git.c
@@@ -272,14 -272,9 +272,14 @@@ static int run_command(struct cmd_struc
                prefix = setup_git_directory();
        if (p->option & USE_PAGER)
                setup_pager();
 -      if ((p->option & NEED_WORK_TREE) &&
 -          (!is_inside_work_tree() || is_inside_git_dir()))
 -              die("%s must be run in a work tree", p->cmd);
 +      if (p->option & NEED_WORK_TREE) {
 +              const char *work_tree = get_git_work_tree();
 +              const char *git_dir = get_git_dir();
 +              if (!is_absolute_path(git_dir))
 +                      set_git_dir(make_absolute_path(git_dir));
 +              if (!work_tree || chdir(work_tree))
 +                      die("%s must be run in a work tree", p->cmd);
 +      }
        trace_argv_printf(argv, argc, "trace: built-in: git");
  
        status = p->fn(argc, argv, prefix);
@@@ -315,8 -310,7 +315,8 @@@ static void handle_internal_command(in
                { "branch", cmd_branch, RUN_SETUP },
                { "bundle", cmd_bundle },
                { "cat-file", cmd_cat_file, RUN_SETUP },
 -              { "checkout-index", cmd_checkout_index, RUN_SETUP },
 +              { "checkout-index", cmd_checkout_index,
 +                      RUN_SETUP | NEED_WORK_TREE},
                { "check-ref-format", cmd_check_ref_format },
                { "check-attr", cmd_check_attr, RUN_SETUP | NEED_WORK_TREE },
                { "cherry", cmd_cherry, RUN_SETUP },
                { "show", cmd_show, RUN_SETUP | USE_PAGER },
                { "stripspace", cmd_stripspace },
                { "symbolic-ref", cmd_symbolic_ref, RUN_SETUP },
+               { "tag", cmd_tag, RUN_SETUP },
                { "tar-tree", cmd_tar_tree },
                { "unpack-objects", cmd_unpack_objects, RUN_SETUP },
                { "update-index", cmd_update_index, RUN_SETUP },
                { "update-ref", cmd_update_ref, RUN_SETUP },
                { "upload-archive", cmd_upload_archive },
+               { "verify-tag", cmd_verify_tag, RUN_SETUP },
                { "version", cmd_version },
                { "whatchanged", cmd_whatchanged, RUN_SETUP | USE_PAGER },
                { "write-tree", cmd_write_tree, RUN_SETUP },
@@@ -449,11 -445,11 +451,11 @@@ int main(int argc, const char **argv
        cmd = argv[0];
  
        /*
 -       * We search for git commands in the following order:
 -       *  - git_exec_path()
 -       *  - the path of the "git" command if we could find it
 -       *    in $0
 -       *  - the regular PATH.
 +       * We execute external git command via execv_git_cmd(),
 +       * which looks at "--exec-path" option, GIT_EXEC_PATH
 +       * environment, and $(gitexecdir) in Makefile while built,
 +       * in this order.  For scripted commands, we prepend
 +       * the value of the exec_path variable to the PATH.
         */
        if (exec_path)
                prepend_to_path(exec_path, strlen(exec_path));