Merge branch 'eb/quilt'
authorJunio C Hamano <junkio@cox.net>
Fri, 19 May 2006 23:57:11 +0000 (16:57 -0700)
committerJunio C Hamano <junkio@cox.net>
Fri, 19 May 2006 23:57:11 +0000 (16:57 -0700)
* eb/quilt:
  Implement a --dry-run option to git-quiltimport
  Implement git-quiltimport

14 files changed:
Documentation/install-webdoc.sh
Makefile
apply.c
builtin-grep.c
builtin-init-db.c [new file with mode: 0644]
builtin-log.c
builtin.h
cache.h
git-am.sh
git.c
init-db.c [deleted file]
read-cache.c
refs.c
update-index.c

index 50638c7..60211a5 100755 (executable)
@@ -4,12 +4,16 @@ T="$1"
 
 for h in *.html *.txt howto/*.txt howto/*.html
 do
-       diff -u -I'Last updated [0-9][0-9]-[A-Z][a-z][a-z]-' "$T/$h" "$h" || {
+       if test -f "$T/$h" &&
+          diff -u -I'Last updated [0-9][0-9]-[A-Z][a-z][a-z]-' "$T/$h" "$h"
+       then
+               :; # up to date
+       else
                echo >&2 "# install $h $T/$h"
                rm -f "$T/$h"
                mkdir -p `dirname "$T/$h"`
                cp "$h" "$T/$h"
-       }
+       fi
 done
 strip_leading=`echo "$T/" | sed -e 's|.|.|g'`
 for th in "$T"/*.html "$T"/*.txt "$T"/howto/*.txt "$T"/howto/*.html
index 549f953..3a31ce0 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -154,7 +154,7 @@ PROGRAMS = \
        git-convert-objects$X git-diff-files$X \
        git-diff-index$X git-diff-stages$X \
        git-diff-tree$X git-fetch-pack$X git-fsck-objects$X \
-       git-hash-object$X git-index-pack$X git-init-db$X git-local-fetch$X \
+       git-hash-object$X git-index-pack$X git-local-fetch$X \
        git-ls-files$X git-ls-tree$X git-mailinfo$X git-merge-base$X \
        git-merge-index$X git-mktag$X git-mktree$X git-pack-objects$X git-patch-id$X \
        git-peek-remote$X git-prune-packed$X git-read-tree$X \
@@ -170,7 +170,8 @@ PROGRAMS = \
 
 BUILT_INS = git-log$X git-whatchanged$X git-show$X \
        git-count-objects$X git-diff$X git-push$X \
-       git-grep$X git-rev-list$X git-check-ref-format$X
+       git-grep$X git-rev-list$X git-check-ref-format$X \
+       git-init-db$X
 
 # what 'all' will build and 'install' will install, in gitexecdir
 ALL_PROGRAMS = $(PROGRAMS) $(SIMPLE_PROGRAMS) $(SCRIPTS)
@@ -218,7 +219,8 @@ LIB_OBJS = \
 
 BUILTIN_OBJS = \
        builtin-log.o builtin-help.o builtin-count.o builtin-diff.o builtin-push.o \
-       builtin-grep.o builtin-rev-list.o builtin-check-ref-format.o
+       builtin-grep.o builtin-rev-list.o builtin-check-ref-format.o \
+       builtin-init-db.o
 
 GITLIBS = $(LIB_FILE) $(XDIFF_LIB)
 LIBS = $(GITLIBS) -lz
@@ -473,6 +475,7 @@ strip: $(PROGRAMS) git$X
 
 git$X: git.c common-cmds.h $(BUILTIN_OBJS) $(GITLIBS)
        $(CC) -DGIT_VERSION='"$(GIT_VERSION)"' \
+               -DDEFAULT_GIT_TEMPLATE_DIR='"$(template_dir_SQ)"' \
                $(ALL_CFLAGS) -o $@ $(filter %.c,$^) \
                $(BUILTIN_OBJS) $(ALL_LDFLAGS) $(LIBS)
 
@@ -565,10 +568,6 @@ git-http-push$X: revision.o http.o http-push.o $(LIB_FILE)
        $(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \
                $(LIBS) $(CURL_LIBCURL) $(EXPAT_LIBEXPAT)
 
-init-db.o: init-db.c
-       $(CC) -c $(ALL_CFLAGS) \
-               -DDEFAULT_GIT_TEMPLATE_DIR='"$(template_dir_SQ)"' $*.c
-
 $(LIB_OBJS) $(BUILTIN_OBJS): $(LIB_H)
 $(patsubst git-%$X,%.o,$(PROGRAMS)): $(GITLIBS)
 $(DIFF_OBJS): diffcore.h
@@ -652,6 +651,25 @@ dist: git.spec git-tar-tree
 rpm: dist
        $(RPMBUILD) -ta $(GIT_TARNAME).tar.gz
 
+htmldocs = git-htmldocs-$(GIT_VERSION)
+manpages = git-manpages-$(GIT_VERSION)
+dist-doc:
+       rm -fr .doc-tmp-dir
+       mkdir .doc-tmp-dir
+       $(MAKE) -C Documentation WEBDOC_DEST=../.doc-tmp-dir install-webdoc
+       cd .doc-tmp-dir && $(TAR) cf ../$(htmldocs).tar .
+       gzip -n -9 -f $(htmldocs).tar
+       :
+       rm -fr .doc-tmp-dir
+       mkdir .doc-tmp-dir .doc-tmp-dir/man1 .doc-tmp-dir/man7
+       $(MAKE) -C Documentation DESTDIR=. \
+               man1=../.doc-tmp-dir/man1 \
+               man7=../.doc-tmp-dir/man7 \
+               install
+       cd .doc-tmp-dir && $(TAR) cf ../$(manpages).tar .
+       gzip -n -9 -f $(manpages).tar
+       rm -fr .doc-tmp-dir
+
 ### Cleaning rules
 
 clean:
@@ -659,8 +677,9 @@ clean:
                $(LIB_FILE) $(XDIFF_LIB)
        rm -f $(ALL_PROGRAMS) $(BUILT_INS) git$X
        rm -f *.spec *.pyc *.pyo */*.pyc */*.pyo common-cmds.h TAGS tags
-       rm -rf $(GIT_TARNAME)
+       rm -rf $(GIT_TARNAME) .doc-tmp-dir
        rm -f $(GIT_TARNAME).tar.gz git-core_$(GIT_VERSION)-*.tar.gz
+       rm -f $(htmldocs).tar $(manpages).tar
        $(MAKE) -C Documentation/ clean
        $(MAKE) -C templates clean
        $(MAKE) -C t/ clean
diff --git a/apply.c b/apply.c
index 7c8146a..b3b9b40 100644 (file)
--- a/apply.c
+++ b/apply.c
@@ -17,6 +17,8 @@
 //  --stat does just a diffstat, and doesn't actually apply
 //  --numstat does numeric diffstat, and doesn't actually apply
 //  --index-info shows the old and new index info for paths if available.
+//  --index updates the cache as well.
+//  --cached updates only the cache without ever touching the working tree.
 //
 static const char *prefix;
 static int prefix_length = -1;
@@ -26,6 +28,7 @@ static int p_value = 1;
 static int allow_binary_replacement = 0;
 static int check_index = 0;
 static int write_index = 0;
+static int cached = 0;
 static int diffstat = 0;
 static int numstat = 0;
 static int summary = 0;
@@ -36,7 +39,7 @@ static int show_index_info = 0;
 static int line_termination = '\n';
 static unsigned long p_context = -1;
 static const char apply_usage[] =
-"git-apply [--stat] [--numstat] [--summary] [--check] [--index] [--apply] [--no-add] [--index-info] [--allow-binary-replacement] [-z] [-pNUM] [-CNUM] [--whitespace=<nowarn|warn|error|error-all|strip>] <patch>...";
+"git-apply [--stat] [--numstat] [--summary] [--check] [--index] [--cached] [--apply] [--no-add] [--index-info] [--allow-binary-replacement] [-z] [-pNUM] [-CNUM] [--whitespace=<nowarn|warn|error|error-all|strip>] <patch>...";
 
 static enum whitespace_eol {
        nowarn_whitespace,
@@ -1600,7 +1603,7 @@ static int apply_fragments(struct buffer_desc *desc, struct patch *patch)
        return 0;
 }
 
-static int apply_data(struct patch *patch, struct stat *st)
+static int apply_data(struct patch *patch, struct stat *st, struct cache_entry *ce)
 {
        char *buf;
        unsigned long size, alloc;
@@ -1609,7 +1612,17 @@ static int apply_data(struct patch *patch, struct stat *st)
        size = 0;
        alloc = 0;
        buf = NULL;
-       if (patch->old_name) {
+       if (cached) {
+               if (ce) {
+                       char type[20];
+                       buf = read_sha1_file(ce->sha1, type, &size);
+                       if (!buf)
+                               return error("read of %s failed",
+                                            patch->old_name);
+                       alloc = size;
+               }
+       }
+       else if (patch->old_name) {
                size = st->st_size;
                alloc = size + 8192;
                buf = xmalloc(alloc);
@@ -1637,16 +1650,21 @@ static int check_patch(struct patch *patch)
        const char *old_name = patch->old_name;
        const char *new_name = patch->new_name;
        const char *name = old_name ? old_name : new_name;
+       struct cache_entry *ce = NULL;
 
        if (old_name) {
-               int changed;
-               int stat_ret = lstat(old_name, &st);
+               int changed = 0;
+               int stat_ret = 0;
+               unsigned st_mode = 0;
 
+               if (!cached)
+                       stat_ret = lstat(old_name, &st);
                if (check_index) {
                        int pos = cache_name_pos(old_name, strlen(old_name));
                        if (pos < 0)
                                return error("%s: does not exist in index",
                                             old_name);
+                       ce = active_cache[pos];
                        if (stat_ret < 0) {
                                struct checkout costate;
                                if (errno != ENOENT)
@@ -1659,37 +1677,41 @@ static int check_patch(struct patch *patch)
                                costate.quiet = 0;
                                costate.not_new = 0;
                                costate.refresh_cache = 1;
-                               if (checkout_entry(active_cache[pos],
+                               if (checkout_entry(ce,
                                                   &costate,
                                                   NULL) ||
                                    lstat(old_name, &st))
                                        return -1;
                        }
-
-                       changed = ce_match_stat(active_cache[pos], &st, 1);
+                       if (!cached)
+                               changed = ce_match_stat(ce, &st, 1);
                        if (changed)
                                return error("%s: does not match index",
                                             old_name);
+                       if (cached)
+                               st_mode = ntohl(ce->ce_mode);
                }
                else if (stat_ret < 0)
                        return error("%s: %s", old_name, strerror(errno));
 
+               if (!cached)
+                       st_mode = ntohl(create_ce_mode(st.st_mode));
+
                if (patch->is_new < 0)
                        patch->is_new = 0;
-               st.st_mode = ntohl(create_ce_mode(st.st_mode));
                if (!patch->old_mode)
-                       patch->old_mode = st.st_mode;
-               if ((st.st_mode ^ patch->old_mode) & S_IFMT)
+                       patch->old_mode = st_mode;
+               if ((st_mode ^ patch->old_mode) & S_IFMT)
                        return error("%s: wrong type", old_name);
-               if (st.st_mode != patch->old_mode)
+               if (st_mode != patch->old_mode)
                        fprintf(stderr, "warning: %s has type %o, expected %o\n",
-                               old_name, st.st_mode, patch->old_mode);
+                               old_name, st_mode, patch->old_mode);
        }
 
        if (new_name && (patch->is_new | patch->is_rename | patch->is_copy)) {
                if (check_index && cache_name_pos(new_name, strlen(new_name)) >= 0)
                        return error("%s: already exists in index", new_name);
-               if (!lstat(new_name, &st))
+               if (!cached && !lstat(new_name, &st))
                        return error("%s: already exists in working directory", new_name);
                if (errno != ENOENT)
                        return error("%s: %s", new_name, strerror(errno));
@@ -1709,9 +1731,9 @@ static int check_patch(struct patch *patch)
                        return error("new mode (%o) of %s does not match old mode (%o)%s%s",
                                patch->new_mode, new_name, patch->old_mode,
                                same ? "" : " of ", same ? "" : old_name);
-       }       
+       }
 
-       if (apply_data(patch, &st) < 0)
+       if (apply_data(patch, &st, ce) < 0)
                return error("%s: patch does not apply", name);
        return 0;
 }
@@ -1778,7 +1800,7 @@ static void numstat_patch_list(struct patch *patch)
 {
        for ( ; patch; patch = patch->next) {
                const char *name;
-               name = patch->old_name ? patch->old_name : patch->new_name;
+               name = patch->new_name ? patch->new_name : patch->old_name;
                printf("%d\t%d\t", patch->lines_added, patch->lines_deleted);
                if (line_termination && quote_c_style(name, NULL, NULL, 0))
                        quote_c_style(name, NULL, stdout, 0);
@@ -1894,7 +1916,8 @@ static void remove_file(struct patch *patch)
                if (remove_file_from_cache(patch->old_name) < 0)
                        die("unable to remove %s from index", patch->old_name);
        }
-       unlink(patch->old_name);
+       if (!cached)
+               unlink(patch->old_name);
 }
 
 static void add_index_file(const char *path, unsigned mode, void *buf, unsigned long size)
@@ -1911,9 +1934,11 @@ static void add_index_file(const char *path, unsigned mode, void *buf, unsigned
        memcpy(ce->name, path, namelen);
        ce->ce_mode = create_ce_mode(mode);
        ce->ce_flags = htons(namelen);
-       if (lstat(path, &st) < 0)
-               die("unable to stat newly created file %s", path);
-       fill_stat_cache_info(ce, &st);
+       if (!cached) {
+               if (lstat(path, &st) < 0)
+                       die("unable to stat newly created file %s", path);
+               fill_stat_cache_info(ce, &st);
+       }
        if (write_sha1_file(buf, size, blob_type, ce->sha1) < 0)
                die("unable to create backing store for newly created file %s", path);
        if (add_cache_entry(ce, ADD_CACHE_OK_TO_ADD) < 0)
@@ -1950,6 +1975,8 @@ static int try_create_file(const char *path, unsigned int mode, const char *buf,
  */
 static void create_one_file(char *path, unsigned mode, const char *buf, unsigned long size)
 {
+       if (cached)
+               return;
        if (!try_create_file(path, mode, buf, size))
                return;
 
@@ -2182,6 +2209,11 @@ int main(int argc, char **argv)
                        check_index = 1;
                        continue;
                }
+               if (!strcmp(arg, "--cached")) {
+                       check_index = 1;
+                       cached = 1;
+                       continue;
+               }
                if (!strcmp(arg, "--apply")) {
                        apply = 1;
                        continue;
index 66111de..d09ddf0 100644 (file)
@@ -453,7 +453,6 @@ static int external_grep(struct grep_opt *opt, const char **paths, int cached)
 
        len = nr = 0;
        push_arg("grep");
-       push_arg("-H");
        if (opt->fixed)
                push_arg("-F");
        if (opt->linenum)
@@ -503,17 +502,35 @@ static int external_grep(struct grep_opt *opt, const char **paths, int cached)
                push_arg("-e");
                push_arg(p->pattern);
        }
-       push_arg("--");
+
+       /*
+        * To make sure we get the header printed out when we want it,
+        * add /dev/null to the paths to grep.  This is unnecessary
+        * (and wrong) with "-l" or "-L", which always print out the
+        * name anyway.
+        *
+        * GNU grep has "-H", but this is portable.
+        */
+       if (!opt->name_only && !opt->unmatch_name_only)
+               push_arg("/dev/null");
 
        hit = 0;
        argc = nr;
        for (i = 0; i < active_nr; i++) {
                struct cache_entry *ce = active_cache[i];
+               const char *name;
                if (ce_stage(ce) || !S_ISREG(ntohl(ce->ce_mode)))
                        continue;
                if (!pathspec_matches(paths, ce->name))
                        continue;
-               argv[argc++] = ce->name;
+               name = ce->name;
+               if (name[0] == '-') {
+                       int len = ce_namelen(ce);
+                       name = xmalloc(len + 3);
+                       memcpy(name, "./", 2);
+                       memcpy(name + 2, ce->name, len + 1);
+               }
+               argv[argc++] = name;
                if (argc < MAXARGS)
                        continue;
                hit += exec_grep(argc, argv);
diff --git a/builtin-init-db.c b/builtin-init-db.c
new file mode 100644 (file)
index 0000000..2a1384c
--- /dev/null
@@ -0,0 +1,293 @@
+/*
+ * GIT - The information manager from hell
+ *
+ * Copyright (C) Linus Torvalds, 2005
+ */
+#include "cache.h"
+#include "builtin.h"
+
+#ifndef DEFAULT_GIT_TEMPLATE_DIR
+#define DEFAULT_GIT_TEMPLATE_DIR "/usr/share/git-core/templates/"
+#endif
+
+static void safe_create_dir(const char *dir, int share)
+{
+       if (mkdir(dir, 0777) < 0) {
+               if (errno != EEXIST) {
+                       perror(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)
+{
+       int fdi, fdo, status;
+
+       mode = (mode & 0111) ? 0777 : 0666;
+       if ((fdi = open(src, O_RDONLY)) < 0)
+               return fdi;
+       if ((fdo = open(dst, O_WRONLY | O_CREAT | O_EXCL, mode)) < 0) {
+               close(fdi);
+               return fdo;
+       }
+       status = copy_fd(fdi, fdo);
+       close(fdo);
+
+       if (!status && adjust_shared_perm(dst))
+               return -1;
+
+       return status;
+}
+
+static void copy_templates_1(char *path, int baselen,
+                            char *template, int template_baselen,
+                            DIR *dir)
+{
+       struct dirent *de;
+
+       /* Note: if ".git/hooks" file exists in the repository being
+        * re-initialized, /etc/core-git/templates/hooks/update would
+        * cause git-init-db to fail here.  I think this is sane but
+        * it means that the set of templates we ship by default, along
+        * with the way the namespace under .git/ is organized, should
+        * be really carefully chosen.
+        */
+       safe_create_dir(path, 1);
+       while ((de = readdir(dir)) != NULL) {
+               struct stat st_git, st_template;
+               int namelen;
+               int exists = 0;
+
+               if (de->d_name[0] == '.')
+                       continue;
+               namelen = strlen(de->d_name);
+               if ((PATH_MAX <= baselen + namelen) ||
+                   (PATH_MAX <= template_baselen + namelen))
+                       die("insanely long template name %s", de->d_name);
+               memcpy(path + baselen, de->d_name, namelen+1);
+               memcpy(template + template_baselen, de->d_name, namelen+1);
+               if (lstat(path, &st_git)) {
+                       if (errno != ENOENT)
+                               die("cannot stat %s", path);
+               }
+               else
+                       exists = 1;
+
+               if (lstat(template, &st_template))
+                       die("cannot stat template %s", template);
+
+               if (S_ISDIR(st_template.st_mode)) {
+                       DIR *subdir = opendir(template);
+                       int baselen_sub = baselen + namelen;
+                       int template_baselen_sub = template_baselen + namelen;
+                       if (!subdir)
+                               die("cannot opendir %s", template);
+                       path[baselen_sub++] =
+                               template[template_baselen_sub++] = '/';
+                       path[baselen_sub] =
+                               template[template_baselen_sub] = 0;
+                       copy_templates_1(path, baselen_sub,
+                                        template, template_baselen_sub,
+                                        subdir);
+                       closedir(subdir);
+               }
+               else if (exists)
+                       continue;
+               else if (S_ISLNK(st_template.st_mode)) {
+                       char lnk[256];
+                       int len;
+                       len = readlink(template, lnk, sizeof(lnk));
+                       if (len < 0)
+                               die("cannot readlink %s", template);
+                       if (sizeof(lnk) <= len)
+                               die("insanely long symlink %s", template);
+                       lnk[len] = 0;
+                       if (symlink(lnk, path))
+                               die("cannot symlink %s %s", lnk, path);
+               }
+               else if (S_ISREG(st_template.st_mode)) {
+                       if (copy_file(path, template, st_template.st_mode))
+                               die("cannot copy %s to %s", template, path);
+               }
+               else
+                       error("ignoring template %s", template);
+       }
+}
+
+static void copy_templates(const char *git_dir, int len, const char *template_dir)
+{
+       char path[PATH_MAX];
+       char template_path[PATH_MAX];
+       int template_len;
+       DIR *dir;
+
+       if (!template_dir)
+               template_dir = DEFAULT_GIT_TEMPLATE_DIR;
+       strcpy(template_path, template_dir);
+       template_len = strlen(template_path);
+       if (template_path[template_len-1] != '/') {
+               template_path[template_len++] = '/';
+               template_path[template_len] = 0;
+       }
+       dir = opendir(template_path);
+       if (!dir) {
+               fprintf(stderr, "warning: templates not found %s\n",
+                       template_dir);
+               return;
+       }
+
+       /* Make sure that template is from the correct vintage */
+       strcpy(template_path + template_len, "config");
+       repository_format_version = 0;
+       git_config_from_file(check_repository_format_version,
+                            template_path);
+       template_path[template_len] = 0;
+
+       if (repository_format_version &&
+           repository_format_version != GIT_REPO_VERSION) {
+               fprintf(stderr, "warning: not copying templates of "
+                       "a wrong format version %d from '%s'\n",
+                       repository_format_version,
+                       template_dir);
+               closedir(dir);
+               return;
+       }
+
+       memcpy(path, git_dir, len);
+       path[len] = 0;
+       copy_templates_1(path, len,
+                        template_path, template_len,
+                        dir);
+       closedir(dir);
+}
+
+static void create_default_files(const char *git_dir, const char *template_path)
+{
+       unsigned len = strlen(git_dir);
+       static char path[PATH_MAX];
+       unsigned char sha1[20];
+       struct stat st1;
+       char repo_version_string[10];
+
+       if (len > sizeof(path)-50)
+               die("insane git directory %s", git_dir);
+       memcpy(path, git_dir, len);
+
+       if (len && path[len-1] != '/')
+               path[len++] = '/';
+
+       /*
+        * Create .git/refs/{heads,tags}
+        */
+       strcpy(path + len, "refs");
+       safe_create_dir(path, 1);
+       strcpy(path + len, "refs/heads");
+       safe_create_dir(path, 1);
+       strcpy(path + len, "refs/tags");
+       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
+        * from it after installing.
+        */
+       path[len] = 0;
+       copy_templates(path, len, template_path);
+
+       git_config(git_default_config);
+
+       /*
+        * Create the default symlink from ".git/HEAD" to the "master"
+        * branch, if it does not exist yet.
+        */
+       strcpy(path + len, "HEAD");
+       if (read_ref(path, sha1) < 0) {
+               if (create_symref(path, "refs/heads/master") < 0)
+                       exit(1);
+       }
+
+       /* This forces creation of new config file */
+       sprintf(repo_version_string, "%d", GIT_REPO_VERSION);
+       git_config_set("core.repositoryformatversion", repo_version_string);
+
+       path[len] = 0;
+       strcpy(path + len, "config");
+
+       /* Check filemode trustability */
+       if (!lstat(path, &st1)) {
+               struct stat st2;
+               int filemode = (!chmod(path, st1.st_mode ^ S_IXUSR) &&
+                               !lstat(path, &st2) &&
+                               st1.st_mode != st2.st_mode);
+               git_config_set("core.filemode",
+                              filemode ? "true" : "false");
+       }
+}
+
+static const char init_db_usage[] =
+"git-init-db [--template=<template-directory>] [--shared]";
+
+/*
+ * If you want to, you can share the DB area with any number of branches.
+ * That has advantages: you can save space by sharing all the SHA1 objects.
+ * On the other hand, it might just make lookup slower and messier. You
+ * be the judge.  The default case is to have one DB per managed directory.
+ */
+int cmd_init_db(int argc, const char **argv, char **envp)
+{
+       const char *git_dir;
+       const char *sha1_dir;
+       const char *template_dir = NULL;
+       char *path;
+       int len, i;
+
+       for (i = 1; i < argc; i++, argv++) {
+               const 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);
+       }
+
+       /*
+        * Set up the default .git directory contents
+        */
+       git_dir = getenv(GIT_DIR_ENVIRONMENT);
+       if (!git_dir) {
+               git_dir = DEFAULT_GIT_DIR_ENVIRONMENT;
+               fprintf(stderr, "defaulting to local storage area\n");
+       }
+       safe_create_dir(git_dir, 0);
+
+       /* Check to see if the repository version is right.
+        * Note that a newly created repository does not have
+        * config file, so this will not fail.  What we are catching
+        * is an attempt to reinitialize new repository with an old tool.
+        */
+       check_repository_format();
+
+       create_default_files(git_dir, template_dir);
+
+       /*
+        * And set up the object store.
+        */
+       sha1_dir = get_object_directory();
+       len = strlen(sha1_dir);
+       path = xmalloc(len + 40);
+       memcpy(path, sha1_dir, len);
+
+       safe_create_dir(sha1_dir, 1);
+       strcpy(path+len, "/pack");
+       safe_create_dir(path, 1);
+       strcpy(path+len, "/info");
+       safe_create_dir(path, 1);
+
+       if (shared_repository)
+               git_config_set("core.sharedRepository", "true");
+
+       return 0;
+}
index 69f2911..c4ceee0 100644 (file)
@@ -19,6 +19,13 @@ static int cmd_log_wc(int argc, const char **argv, char **envp,
        rev->commit_format = CMIT_FMT_DEFAULT;
        rev->verbose_header = 1;
        argc = setup_revisions(argc, argv, rev, "HEAD");
+       if (rev->always_show_header) {
+               if (rev->diffopt.pickaxe || rev->diffopt.filter) {
+                       rev->always_show_header = 0;
+                       if (rev->diffopt.output_format == DIFF_FORMAT_RAW)
+                               rev->diffopt.output_format = DIFF_FORMAT_NO_OUTPUT;
+               }
+       }
 
        if (argc > 1)
                die("unrecognized argument: %s", argv[1]);
index ff559de..6054126 100644 (file)
--- a/builtin.h
+++ b/builtin.h
@@ -26,5 +26,6 @@ extern int cmd_push(int argc, const char **argv, char **envp);
 extern int cmd_grep(int argc, const char **argv, char **envp);
 extern int cmd_rev_list(int argc, const char **argv, char **envp);
 extern int cmd_check_ref_format(int argc, const char **argv, char **envp);
+extern int cmd_init_db(int argc, const char **argv, char **envp);
 
 #endif
diff --git a/cache.h b/cache.h
index 4b7a439..afa8e4f 100644 (file)
--- a/cache.h
+++ b/cache.h
@@ -158,6 +158,12 @@ extern int index_pipe(unsigned char *sha1, int fd, const char *type, int write_o
 extern int index_path(unsigned char *sha1, const char *path, struct stat *st, int write_object);
 extern void fill_stat_cache_info(struct cache_entry *ce, struct stat *st);
 
+#define REFRESH_REALLY         0x0001  /* ignore_valid */
+#define REFRESH_UNMERGED       0x0002  /* allow unmerged */
+#define REFRESH_QUIET          0x0004  /* be quiet about it */
+#define REFRESH_IGNORE_MISSING 0x0008  /* ignore non-existent */
+extern int refresh_cache(unsigned int flags);
+
 struct cache_file {
        struct cache_file *next;
        char lockfile[PATH_MAX];
index 33f208c..97ec2d0 100755 (executable)
--- a/git-am.sh
+++ b/git-am.sh
@@ -59,46 +59,12 @@ fall_back_3way () {
        GIT_INDEX_FILE="$dotest/patch-merge-tmp-index" \
        git-write-tree >"$dotest/patch-merge-base+" &&
        # index has the base tree now.
-       (
-           cd "$dotest/patch-merge-tmp-dir" &&
-           GIT_INDEX_FILE="../patch-merge-tmp-index" \
-           GIT_OBJECT_DIRECTORY="$O_OBJECT" \
-           git-apply $binary --index <../patch
-        )
+       GIT_INDEX_FILE="$dotest/patch-merge-tmp-index" \
+       git-apply $binary --cached <"$dotest/patch"
     then
        echo Using index info to reconstruct a base tree...
        mv "$dotest/patch-merge-base+" "$dotest/patch-merge-base"
        mv "$dotest/patch-merge-tmp-index" "$dotest/patch-merge-index"
-    else
-       # Otherwise, try nearby trees that can be used to apply the
-       # patch.
-       (
-           N=10
-
-           # Hoping the patch is against our recent commits...
-           git-rev-list --max-count=$N HEAD
-
-           # or hoping the patch is against known tags...
-           git-ls-remote --tags .
-       ) |
-       while read base junk
-       do
-           # See if we have it as a tree...
-           git-cat-file tree "$base" >/dev/null 2>&1 || continue
-
-           rm -fr "$dotest"/patch-merge-* &&
-           mkdir "$dotest/patch-merge-tmp-dir" || break
-           (
-               cd "$dotest/patch-merge-tmp-dir" &&
-               GIT_INDEX_FILE=../patch-merge-tmp-index &&
-               GIT_OBJECT_DIRECTORY="$O_OBJECT" &&
-               export GIT_INDEX_FILE GIT_OBJECT_DIRECTORY &&
-               git-read-tree "$base" &&
-               git-apply $binary --index &&
-               mv ../patch-merge-tmp-index ../patch-merge-index &&
-               echo "$base" >../patch-merge-base
-           ) <"$dotest/patch"  2>/dev/null && break
-       done
     fi
 
     test -f "$dotest/patch-merge-index" &&
diff --git a/git.c b/git.c
index d0650bb..3216d31 100644 (file)
--- a/git.c
+++ b/git.c
@@ -51,6 +51,7 @@ static void handle_internal_command(int argc, const char **argv, char **envp)
                { "diff", cmd_diff },
                { "grep", cmd_grep },
                { "rev-list", cmd_rev_list },
+               { "init-db", cmd_init_db },
                { "check-ref-format", cmd_check_ref_format }
        };
        int i;
diff --git a/init-db.c b/init-db.c
deleted file mode 100644 (file)
index ff29496..0000000
--- a/init-db.c
+++ /dev/null
@@ -1,291 +0,0 @@
-/*
- * GIT - The information manager from hell
- *
- * Copyright (C) Linus Torvalds, 2005
- */
-#include "cache.h"
-
-#ifndef DEFAULT_GIT_TEMPLATE_DIR
-#define DEFAULT_GIT_TEMPLATE_DIR "/usr/share/git-core/templates/"
-#endif
-
-static void safe_create_dir(const char *dir, int share)
-{
-       if (mkdir(dir, 0777) < 0) {
-               if (errno != EEXIST) {
-                       perror(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)
-{
-       int fdi, fdo, status;
-
-       mode = (mode & 0111) ? 0777 : 0666;
-       if ((fdi = open(src, O_RDONLY)) < 0)
-               return fdi;
-       if ((fdo = open(dst, O_WRONLY | O_CREAT | O_EXCL, mode)) < 0) {
-               close(fdi);
-               return fdo;
-       }
-       status = copy_fd(fdi, fdo);
-       close(fdo);
-
-       if (!status && adjust_shared_perm(dst))
-               return -1;
-
-       return status;
-}
-
-static void copy_templates_1(char *path, int baselen,
-                            char *template, int template_baselen,
-                            DIR *dir)
-{
-       struct dirent *de;
-
-       /* Note: if ".git/hooks" file exists in the repository being
-        * re-initialized, /etc/core-git/templates/hooks/update would
-        * cause git-init-db to fail here.  I think this is sane but
-        * it means that the set of templates we ship by default, along
-        * with the way the namespace under .git/ is organized, should
-        * be really carefully chosen.
-        */
-       safe_create_dir(path, 1);
-       while ((de = readdir(dir)) != NULL) {
-               struct stat st_git, st_template;
-               int namelen;
-               int exists = 0;
-
-               if (de->d_name[0] == '.')
-                       continue;
-               namelen = strlen(de->d_name);
-               if ((PATH_MAX <= baselen + namelen) ||
-                   (PATH_MAX <= template_baselen + namelen))
-                       die("insanely long template name %s", de->d_name);
-               memcpy(path + baselen, de->d_name, namelen+1);
-               memcpy(template + template_baselen, de->d_name, namelen+1);
-               if (lstat(path, &st_git)) {
-                       if (errno != ENOENT)
-                               die("cannot stat %s", path);
-               }
-               else
-                       exists = 1;
-
-               if (lstat(template, &st_template))
-                       die("cannot stat template %s", template);
-
-               if (S_ISDIR(st_template.st_mode)) {
-                       DIR *subdir = opendir(template);
-                       int baselen_sub = baselen + namelen;
-                       int template_baselen_sub = template_baselen + namelen;
-                       if (!subdir)
-                               die("cannot opendir %s", template);
-                       path[baselen_sub++] =
-                               template[template_baselen_sub++] = '/';
-                       path[baselen_sub] =
-                               template[template_baselen_sub] = 0;
-                       copy_templates_1(path, baselen_sub,
-                                        template, template_baselen_sub,
-                                        subdir);
-                       closedir(subdir);
-               }
-               else if (exists)
-                       continue;
-               else if (S_ISLNK(st_template.st_mode)) {
-                       char lnk[256];
-                       int len;
-                       len = readlink(template, lnk, sizeof(lnk));
-                       if (len < 0)
-                               die("cannot readlink %s", template);
-                       if (sizeof(lnk) <= len)
-                               die("insanely long symlink %s", template);
-                       lnk[len] = 0;
-                       if (symlink(lnk, path))
-                               die("cannot symlink %s %s", lnk, path);
-               }
-               else if (S_ISREG(st_template.st_mode)) {
-                       if (copy_file(path, template, st_template.st_mode))
-                               die("cannot copy %s to %s", template, path);
-               }
-               else
-                       error("ignoring template %s", template);
-       }
-}
-
-static void copy_templates(const char *git_dir, int len, char *template_dir)
-{
-       char path[PATH_MAX];
-       char template_path[PATH_MAX];
-       int template_len;
-       DIR *dir;
-
-       if (!template_dir)
-               template_dir = DEFAULT_GIT_TEMPLATE_DIR;
-       strcpy(template_path, template_dir);
-       template_len = strlen(template_path);
-       if (template_path[template_len-1] != '/') {
-               template_path[template_len++] = '/';
-               template_path[template_len] = 0;
-       }
-       dir = opendir(template_path);
-       if (!dir) {
-               fprintf(stderr, "warning: templates not found %s\n",
-                       template_dir);
-               return;
-       }
-
-       /* Make sure that template is from the correct vintage */
-       strcpy(template_path + template_len, "config");
-       repository_format_version = 0;
-       git_config_from_file(check_repository_format_version,
-                            template_path);
-       template_path[template_len] = 0;
-
-       if (repository_format_version &&
-           repository_format_version != GIT_REPO_VERSION) {
-               fprintf(stderr, "warning: not copying templates of "
-                       "a wrong format version %d from '%s'\n",
-                       repository_format_version,
-                       template_dir);
-               closedir(dir);
-               return;
-       }
-
-       memcpy(path, git_dir, len);
-       path[len] = 0;
-       copy_templates_1(path, len,
-                        template_path, template_len,
-                        dir);
-       closedir(dir);
-}
-
-static void create_default_files(const char *git_dir, char *template_path)
-{
-       unsigned len = strlen(git_dir);
-       static char path[PATH_MAX];
-       unsigned char sha1[20];
-       struct stat st1;
-       char repo_version_string[10];
-
-       if (len > sizeof(path)-50)
-               die("insane git directory %s", git_dir);
-       memcpy(path, git_dir, len);
-
-       if (len && path[len-1] != '/')
-               path[len++] = '/';
-
-       /*
-        * Create .git/refs/{heads,tags}
-        */
-       strcpy(path + len, "refs");
-       safe_create_dir(path, 1);
-       strcpy(path + len, "refs/heads");
-       safe_create_dir(path, 1);
-       strcpy(path + len, "refs/tags");
-       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
-        * from it after installing.
-        */
-       path[len] = 0;
-       copy_templates(path, len, template_path);
-
-       git_config(git_default_config);
-
-       /*
-        * Create the default symlink from ".git/HEAD" to the "master"
-        * branch, if it does not exist yet.
-        */
-       strcpy(path + len, "HEAD");
-       if (read_ref(path, sha1) < 0) {
-               if (create_symref(path, "refs/heads/master") < 0)
-                       exit(1);
-       }
-
-       /* This forces creation of new config file */
-       sprintf(repo_version_string, "%d", GIT_REPO_VERSION);
-       git_config_set("core.repositoryformatversion", repo_version_string);
-
-       path[len] = 0;
-       strcpy(path + len, "config");
-
-       /* Check filemode trustability */
-       if (!lstat(path, &st1)) {
-               struct stat st2;
-               int filemode = (!chmod(path, st1.st_mode ^ S_IXUSR) &&
-                               !lstat(path, &st2) &&
-                               st1.st_mode != st2.st_mode);
-               git_config_set("core.filemode",
-                              filemode ? "true" : "false");
-       }
-}
-
-static const char init_db_usage[] =
-"git-init-db [--template=<template-directory>] [--shared]";
-
-/*
- * If you want to, you can share the DB area with any number of branches.
- * That has advantages: you can save space by sharing all the SHA1 objects.
- * On the other hand, it might just make lookup slower and messier. You
- * be the judge.  The default case is to have one DB per managed directory.
- */
-int main(int argc, char **argv)
-{
-       const char *git_dir;
-       const char *sha1_dir;
-       char *path, *template_dir = NULL;
-       int len, i;
-
-       for (i = 1; i < argc; i++, 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);
-       }
-
-       /*
-        * Set up the default .git directory contents
-        */
-       git_dir = getenv(GIT_DIR_ENVIRONMENT);
-       if (!git_dir) {
-               git_dir = DEFAULT_GIT_DIR_ENVIRONMENT;
-               fprintf(stderr, "defaulting to local storage area\n");
-       }
-       safe_create_dir(git_dir, 0);
-
-       /* Check to see if the repository version is right.
-        * Note that a newly created repository does not have
-        * config file, so this will not fail.  What we are catching
-        * is an attempt to reinitialize new repository with an old tool.
-        */
-       check_repository_format();
-
-       create_default_files(git_dir, template_dir);
-
-       /*
-        * And set up the object store.
-        */
-       sha1_dir = get_object_directory();
-       len = strlen(sha1_dir);
-       path = xmalloc(len + 40);
-       memcpy(path, sha1_dir, len);
-
-       safe_create_dir(sha1_dir, 1);
-       strcpy(path+len, "/pack");
-       safe_create_dir(path, 1);
-       strcpy(path+len, "/info");
-       safe_create_dir(path, 1);
-
-       if (shared_repository)
-               git_config_set("core.sharedRepository", "true");
-
-       return 0;
-}
index a917ab0..b95edcc 100644 (file)
@@ -496,6 +496,123 @@ int add_cache_entry(struct cache_entry *ce, int option)
        return 0;
 }
 
+/* Three functions to allow overloaded pointer return; see linux/err.h */
+static inline void *ERR_PTR(long error)
+{
+       return (void *) error;
+}
+
+static inline long PTR_ERR(const void *ptr)
+{
+       return (long) ptr;
+}
+
+static inline long IS_ERR(const void *ptr)
+{
+       return (unsigned long)ptr > (unsigned long)-1000L;
+}
+
+/*
+ * "refresh" does not calculate a new sha1 file or bring the
+ * cache up-to-date for mode/content changes. But what it
+ * _does_ do is to "re-match" the stat information of a file
+ * with the cache, so that you can refresh the cache for a
+ * file that hasn't been changed but where the stat entry is
+ * out of date.
+ *
+ * For example, you'd want to do this after doing a "git-read-tree",
+ * to link up the stat cache details with the proper files.
+ */
+static struct cache_entry *refresh_entry(struct cache_entry *ce, int really)
+{
+       struct stat st;
+       struct cache_entry *updated;
+       int changed, size;
+
+       if (lstat(ce->name, &st) < 0)
+               return ERR_PTR(-errno);
+
+       changed = ce_match_stat(ce, &st, really);
+       if (!changed) {
+               if (really && assume_unchanged &&
+                   !(ce->ce_flags & htons(CE_VALID)))
+                       ; /* mark this one VALID again */
+               else
+                       return NULL;
+       }
+
+       if (ce_modified(ce, &st, really))
+               return ERR_PTR(-EINVAL);
+
+       size = ce_size(ce);
+       updated = xmalloc(size);
+       memcpy(updated, ce, size);
+       fill_stat_cache_info(updated, &st);
+
+       /* In this case, if really is not set, we should leave
+        * CE_VALID bit alone.  Otherwise, paths marked with
+        * --no-assume-unchanged (i.e. things to be edited) will
+        * reacquire CE_VALID bit automatically, which is not
+        * really what we want.
+        */
+       if (!really && assume_unchanged && !(ce->ce_flags & htons(CE_VALID)))
+               updated->ce_flags &= ~htons(CE_VALID);
+
+       return updated;
+}
+
+int refresh_cache(unsigned int flags)
+{
+       int i;
+       int has_errors = 0;
+       int really = (flags & REFRESH_REALLY) != 0;
+       int allow_unmerged = (flags & REFRESH_UNMERGED) != 0;
+       int quiet = (flags & REFRESH_QUIET) != 0;
+       int not_new = (flags & REFRESH_IGNORE_MISSING) != 0;
+
+       for (i = 0; i < active_nr; i++) {
+               struct cache_entry *ce, *new;
+               ce = active_cache[i];
+               if (ce_stage(ce)) {
+                       while ((i < active_nr) &&
+                              ! strcmp(active_cache[i]->name, ce->name))
+                               i++;
+                       i--;
+                       if (allow_unmerged)
+                               continue;
+                       printf("%s: needs merge\n", ce->name);
+                       has_errors = 1;
+                       continue;
+               }
+
+               new = refresh_entry(ce, really);
+               if (!new)
+                       continue;
+               if (IS_ERR(new)) {
+                       if (not_new && PTR_ERR(new) == -ENOENT)
+                               continue;
+                       if (really && PTR_ERR(new) == -EINVAL) {
+                               /* If we are doing --really-refresh that
+                                * means the index is not valid anymore.
+                                */
+                               ce->ce_flags &= ~htons(CE_VALID);
+                               active_cache_changed = 1;
+                       }
+                       if (quiet)
+                               continue;
+                       printf("%s: needs update\n", ce->name);
+                       has_errors = 1;
+                       continue;
+               }
+               active_cache_changed = 1;
+               /* You can NOT just free active_cache[i] here, since it
+                * might not be necessarily malloc()ed but can also come
+                * from mmap(). */
+               active_cache[i] = new;
+       }
+       return has_errors;
+}
+
 static int verify_hdr(struct cache_header *hdr, unsigned long size)
 {
        SHA_CTX c;
diff --git a/refs.c b/refs.c
index 6c91ae6..0f3491f 100644 (file)
--- a/refs.c
+++ b/refs.c
@@ -220,12 +220,9 @@ static char *ref_lock_file_name(const char *ref)
 
 int get_ref_sha1(const char *ref, unsigned char *sha1)
 {
-       const char *filename;
-
        if (check_ref_format(ref))
                return -1;
-       filename = git_path("refs/%s", ref);
-       return read_ref(filename, sha1);
+       return read_ref(git_path("refs/%s", ref), sha1);
 }
 
 static int lock_ref_file(const char *filename, const char *lock_filename,
index 3d7e02d..7d6de82 100644 (file)
@@ -18,9 +18,6 @@
 static int allow_add;
 static int allow_remove;
 static int allow_replace;
-static int allow_unmerged; /* --refresh needing merge is not error */
-static int not_new; /* --refresh not having working tree files is not error */
-static int quiet; /* --refresh needing update is not error */
 static int info_only;
 static int force_remove;
 static int verbose;
@@ -28,23 +25,6 @@ static int mark_valid_only = 0;
 #define MARK_VALID 1
 #define UNMARK_VALID 2
 
-
-/* Three functions to allow overloaded pointer return; see linux/err.h */
-static inline void *ERR_PTR(long error)
-{
-       return (void *) error;
-}
-
-static inline long PTR_ERR(const void *ptr)
-{
-       return (long) ptr;
-}
-
-static inline long IS_ERR(const void *ptr)
-{
-       return (unsigned long)ptr > (unsigned long)-1000L;
-}
-
 static void report(const char *fmt, ...)
 {
        va_list vp;
@@ -141,103 +121,6 @@ static int add_file_to_cache(const char *path)
 }
 
 /*
- * "refresh" does not calculate a new sha1 file or bring the
- * cache up-to-date for mode/content changes. But what it
- * _does_ do is to "re-match" the stat information of a file
- * with the cache, so that you can refresh the cache for a
- * file that hasn't been changed but where the stat entry is
- * out of date.
- *
- * For example, you'd want to do this after doing a "git-read-tree",
- * to link up the stat cache details with the proper files.
- */
-static struct cache_entry *refresh_entry(struct cache_entry *ce, int really)
-{
-       struct stat st;
-       struct cache_entry *updated;
-       int changed, size;
-
-       if (lstat(ce->name, &st) < 0)
-               return ERR_PTR(-errno);
-
-       changed = ce_match_stat(ce, &st, really);
-       if (!changed) {
-               if (really && assume_unchanged &&
-                   !(ce->ce_flags & htons(CE_VALID)))
-                       ; /* mark this one VALID again */
-               else
-                       return NULL;
-       }
-
-       if (ce_modified(ce, &st, really))
-               return ERR_PTR(-EINVAL);
-
-       size = ce_size(ce);
-       updated = xmalloc(size);
-       memcpy(updated, ce, size);
-       fill_stat_cache_info(updated, &st);
-
-       /* In this case, if really is not set, we should leave
-        * CE_VALID bit alone.  Otherwise, paths marked with
-        * --no-assume-unchanged (i.e. things to be edited) will
-        * reacquire CE_VALID bit automatically, which is not
-        * really what we want.
-        */
-       if (!really && assume_unchanged && !(ce->ce_flags & htons(CE_VALID)))
-               updated->ce_flags &= ~htons(CE_VALID);
-
-       return updated;
-}
-
-static int refresh_cache(int really)
-{
-       int i;
-       int has_errors = 0;
-
-       for (i = 0; i < active_nr; i++) {
-               struct cache_entry *ce, *new;
-               ce = active_cache[i];
-               if (ce_stage(ce)) {
-                       while ((i < active_nr) &&
-                              ! strcmp(active_cache[i]->name, ce->name))
-                               i++;
-                       i--;
-                       if (allow_unmerged)
-                               continue;
-                       printf("%s: needs merge\n", ce->name);
-                       has_errors = 1;
-                       continue;
-               }
-
-               new = refresh_entry(ce, really);
-               if (!new)
-                       continue;
-               if (IS_ERR(new)) {
-                       if (not_new && PTR_ERR(new) == -ENOENT)
-                               continue;
-                       if (really && PTR_ERR(new) == -EINVAL) {
-                               /* If we are doing --really-refresh that
-                                * means the index is not valid anymore.
-                                */
-                               ce->ce_flags &= ~htons(CE_VALID);
-                               active_cache_changed = 1;
-                       }
-                       if (quiet)
-                               continue;
-                       printf("%s: needs update\n", ce->name);
-                       has_errors = 1;
-                       continue;
-               }
-               active_cache_changed = 1;
-               /* You can NOT just free active_cache[i] here, since it
-                * might not be necessarily malloc()ed but can also come
-                * from mmap(). */
-               active_cache[i] = new;
-       }
-       return has_errors;
-}
-
-/*
  * We fundamentally don't like some paths: we don't want
  * dot or dot-dot anywhere, and for obvious reasons don't
  * want to recurse into ".git" either.
@@ -653,6 +536,7 @@ int main(int argc, const char **argv)
        const char *prefix = setup_git_directory();
        int prefix_length = prefix ? strlen(prefix) : 0;
        char set_executable_bit = 0;
+       unsigned int refresh_flags = 0;
 
        git_config(git_default_config);
 
@@ -673,7 +557,7 @@ int main(int argc, const char **argv)
                                continue;
                        }
                        if (!strcmp(path, "-q")) {
-                               quiet = 1;
+                               refresh_flags |= REFRESH_QUIET;
                                continue;
                        }
                        if (!strcmp(path, "--add")) {
@@ -689,15 +573,15 @@ int main(int argc, const char **argv)
                                continue;
                        }
                        if (!strcmp(path, "--unmerged")) {
-                               allow_unmerged = 1;
+                               refresh_flags |= REFRESH_UNMERGED;
                                continue;
                        }
                        if (!strcmp(path, "--refresh")) {
-                               has_errors |= refresh_cache(0);
+                               has_errors |= refresh_cache(refresh_flags);
                                continue;
                        }
                        if (!strcmp(path, "--really-refresh")) {
-                               has_errors |= refresh_cache(1);
+                               has_errors |= refresh_cache(REFRESH_REALLY | refresh_flags);
                                continue;
                        }
                        if (!strcmp(path, "--cacheinfo")) {
@@ -770,7 +654,7 @@ int main(int argc, const char **argv)
                                goto finish;
                        }
                        if (!strcmp(path, "--ignore-missing")) {
-                               not_new = 1;
+                               refresh_flags |= REFRESH_IGNORE_MISSING;
                                continue;
                        }
                        if (!strcmp(path, "--verbose")) {