Merge tag 'post183-for-junio' of http://github.com/msysgit/git
authorJunio C Hamano <gitster@pobox.com>
Fri, 7 Jun 2013 14:38:37 +0000 (07:38 -0700)
committerJunio C Hamano <gitster@pobox.com>
Fri, 7 Jun 2013 14:38:37 +0000 (07:38 -0700)
Collected msysgit build patches for upstream

This set of patches collects a number of build fixes that have been
used on the msysgit port for a while and merging upstream should
simplify future maintenance.

* tag 'post183-for-junio' of http://github.com/msysgit/git:
Set the default help format to html for msys builds.
Ensure the resource file is rebuilt when the version changes.
Windows resource: handle dashes in the Git version gracefully
Provide a Windows version resource for the git executables.
msysgit: Add the --large-address-aware linker directive to the makefile.
Define NO_GETTEXT for Git for Windows
Makefile: Do not use OLD_ICONV on MINGW anymore

40 files changed:
Documentation/RelNotes/1.8.4.txt
Documentation/git-index-pack.txt
Documentation/git-push.txt
Documentation/urls.txt
Makefile
archive-zip.c
builtin.h
builtin/clone.c
builtin/commit.c
builtin/index-pack.c
builtin/prune-packed.c
builtin/prune.c
builtin/push.c
commit.h
config.c
connected.c
connected.h
contrib/completion/git-prompt.sh
contrib/subtree/git-subtree.sh
fetch-pack.c
fetch-pack.h
git-bisect.sh
git-compat-util.h
git-difftool.perl
git-send-email.perl
git.c
remote.c
shallow.c
t/README
t/t3403-rebase-skip.sh
t/t3404-rebase-interactive.sh
t/t3505-cherry-pick-empty.sh
t/t5500-fetch-pack.sh
t/t7502-commit.sh
t/t7800-difftool.sh
t/t9001-send-email.sh
t/t9903-bash-prompt.sh
transport-helper.c
transport.c
transport.h
index 14835d15394ab020615749f1fa40d894424abd6f..6dda09560e8316fc8c0ce66f5cd86a29fddcb592 100644 (file)
@@ -9,6 +9,10 @@ Foreign interface
  * Remote transport helper has been updated to report errors and
    maintain ref hierarchy used to keep track of its own state better.
 
+ * With "export" remote-helper protocol, (1) a push that tries to
+   update a remote ref whose name is different from the pushing side
+   does not work yet, and (2) the helper may not know how to do
+   --dry-run; these problematic cases are disabled for now.
 
 UI, Workflows & Features
 
@@ -16,7 +20,7 @@ UI, Workflows & Features
    more like "check-attr" over bidi-pipes.
 
  * "git describe" learned "--first-parent" option to limit its closest
-   tagged commmit search to the first-parent chain.
+   tagged commit search to the first-parent chain.
 
  * "git merge foo" that might have meant "git merge origin/foo" is
    diagnosed with a more informative error message.
@@ -32,14 +36,24 @@ UI, Workflows & Features
 
  * Updates to completion (both bash and zsh) helpers.
 
+ * The behaviour of the "--chain-reply-to" option of "git send-email"
+   have changed at 1.7.0, and we added a warning/advice message to
+   help users adjust to the new behaviour back then, but we kept it
+   around for too long.  The message has finally been removed.
+
  * "git fetch origin master" unlike "git fetch origin" or "git fetch"
    did not update "refs/remotes/origin/master"; this was an early
    design decision to keep the update of remote tracking branches
    predictable, but in practice it turns out that people find it more
-   convenient to opportunisticly update them whenever we have a
+   convenient to opportunistically update them whenever we have a
    chance, and we have been updating them when we run "git push" which
    already breaks the original "predictability" anyway.
 
+ * The configuration variable core.checkstat was advertised in the
+   documentation but the code expected core.statinfo instead.
+   For now, we accept both core.checkstat and core.statinfo, but the
+   latter will be removed in the longer term.
+
 
 Performance, Internal Implementation, etc.
 
@@ -57,6 +71,9 @@ Performance, Internal Implementation, etc.
    inconsistently between the test framework and t/Makefile, and logic
    to summarize the results looked at a wrong place.
 
+ * "git clone" uses a lighter-weight implementation when making sure
+   that the history behind refs are complete.
+
  * Many warnings from sparse source checker in compat/ area has been
    squelched.
 
@@ -74,6 +91,47 @@ Unless otherwise noted, all the fixes since v1.8.3 in the maintenance
 track are contained in this release (see release notes to them for
 details).
 
+ * "difftool --dir-diff" did not copy back changes made by the
+   end-user in the diff tool backend to the working tree in some
+   cases.
+   (merge 32eaf1d ks/difftool-dir-diff-copy-fix later to maint).
+
+ * "git push $there HEAD:branch" did not resolve HEAD early enough, so
+   it was easy to flip it around while push is still going on and push
+   out a branch that the user did not originally intended when the
+   command was started.
+   (merge 0f075b2 rr/push-head later to maint).
+
+ * The bash prompt code (in contrib/) displayed the name of the branch
+   being rebased when "rebase -i/-m/-p" modes are in use, but not the
+   plain vanilla "rebase".
+   (merge 1306321 fc/show-branch-in-rebase-am later to maint).
+
+ * Handling of negative exclude pattern for directories "!dir" was
+   broken in the update to v1.8.3.
+   (merge c3c327d kb/status-ignored-optim-2 later to maint).
+
+ * zsh prompt script that borrowed from bash prompt script did not
+   work due to slight differences in array variable notation between
+   these two shells.
+   (merge d0583da tg/maint-zsh-svn-remote-prompt later to maint).
+
+ * An entry for "file://" scheme in the enumeration of URL types Git
+   can take in the HTML documentation was made into a clickable link
+   by mistake.
+   (merge 4c32e36 nd/urls-doc-no-file-hyperlink-fix later to maint).
+
+ * "git push --[no-]verify" was not documented.
+   (merge 90d32d1 tr/push-no-verify-doc later to maint).
+
+ * Stop installing the git-remote-testpy script that is only used for
+   testing.
+   (merge 416fda6 fc/makefile later to maint).
+
+ * "git commit --allow-empty-message -m ''" should not start an
+   editor.
+   (merge 2520677 rs/commit-m-no-edit later to maint).
+
  * "git merge @{-1}~22" was rewritten to "git merge frotz@{1}~22"
    incorrectly when your previous branch was "frotz" (it should be
    rewritten to "git merge frotz~22" instead).
index bde8eec30db19accd80d960518b45fbc29f37bf8..7a4e0555205be5d8bb26e5a183f1552cc057637a 100644 (file)
@@ -74,6 +74,9 @@ OPTIONS
 --strict::
        Die, if the pack contains broken objects or links.
 
+--check-self-contained-and-connected::
+       Die if the pack contains broken links. For internal use only.
+
 --threads=<n>::
        Specifies the number of threads to spawn when resolving
        deltas. This requires that index-pack be compiled with
index d51481394c08ef6e0706bc6ff0ccd6908cddc7b8..df5be268ba69f34fe5e91c3148f8af8c1e0091d6 100644 (file)
@@ -11,7 +11,7 @@ SYNOPSIS
 [verse]
 'git push' [--all | --mirror | --tags] [--follow-tags] [-n | --dry-run] [--receive-pack=<git-receive-pack>]
           [--repo=<repository>] [-f | --force] [--prune] [-v | --verbose] [-u | --set-upstream]
-          [<repository> [<refspec>...]]
+          [--no-verify] [<repository> [<refspec>...]]
 
 DESCRIPTION
 -----------
@@ -195,6 +195,11 @@ useful if you write an alias or script around 'git push'.
        be pushed. If on-demand was not able to push all necessary
        revisions it will also be aborted and exit with non-zero status.
 
+--[no-]verify::
+       Toggle the pre-push hook (see linkgit:githooks[5]).  The
+       default is \--verify, giving the hook a chance to prevent the
+       push.  With \--no-verify, the hook is bypassed completely.
+
 
 include::urls-remotes.txt[]
 
index 476e3381c5d40725910bee7fd9d35e7b007ac253..5e185f87c20a2124a7fb9bf2046f6035942b4f92 100644 (file)
@@ -39,7 +39,7 @@ For local repositories, also supported by Git natively, the following
 syntaxes may be used:
 
 - /path/to/repo.git/
-- file:///path/to/repo.git/
+- \file:///path/to/repo.git/
 
 ifndef::git-clone[]
 These two syntaxes are mostly equivalent, except when cloning, when
index a163a75b4e957294ac9f93d3d2a0e37f53ee3b3e..a748133ae51515a2e08bb2dfc0f731d96abda8df 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -495,11 +495,17 @@ SCRIPT_PERL += git-svn.perl
 SCRIPT_PYTHON += git-remote-testpy.py
 SCRIPT_PYTHON += git-p4.py
 
+NO_INSTALL += git-remote-testpy
+
 # Generated files for scripts
 SCRIPT_SH_GEN = $(patsubst %.sh,%,$(SCRIPT_SH))
 SCRIPT_PERL_GEN = $(patsubst %.perl,%,$(SCRIPT_PERL))
 SCRIPT_PYTHON_GEN = $(patsubst %.py,%,$(SCRIPT_PYTHON))
 
+SCRIPT_SH_INS = $(filter-out $(NO_INSTALL),$(SCRIPT_SH_GEN))
+SCRIPT_PERL_INS = $(filter-out $(NO_INSTALL),$(SCRIPT_PERL_GEN))
+SCRIPT_PYTHON_INS = $(filter-out $(NO_INSTALL),$(SCRIPT_PYTHON_GEN))
+
 # Individual rules to allow e.g.
 # "make -C ../.. SCRIPT_PERL=contrib/foo/bar.perl build-perl-script"
 # from subdirectories like contrib/*/
@@ -509,12 +515,12 @@ build-sh-script: $(SCRIPT_SH_GEN)
 build-python-script: $(SCRIPT_PYTHON_GEN)
 
 .PHONY: install-perl-script install-sh-script install-python-script
-install-sh-script: $(SCRIPT_SH_GEN)
-       $(INSTALL) $(SCRIPT_SH_GEN) '$(DESTDIR_SQ)$(gitexec_instdir_SQ)'
-install-perl-script: $(SCRIPT_PERL_GEN)
-       $(INSTALL) $(SCRIPT_PERL_GEN) '$(DESTDIR_SQ)$(gitexec_instdir_SQ)'
-install-python-script: $(SCRIPT_PYTHON_GEN)
-       $(INSTALL) $(SCRIPT_PYTHON_GEN) '$(DESTDIR_SQ)$(gitexec_instdir_SQ)'
+install-sh-script: $(SCRIPT_SH_INS)
+       $(INSTALL) $^ '$(DESTDIR_SQ)$(gitexec_instdir_SQ)'
+install-perl-script: $(SCRIPT_PERL_INS)
+       $(INSTALL) $^ '$(DESTDIR_SQ)$(gitexec_instdir_SQ)'
+install-python-script: $(SCRIPT_PYTHON_INS)
+       $(INSTALL) $^ '$(DESTDIR_SQ)$(gitexec_instdir_SQ)'
 
 .PHONY: clean-perl-script clean-sh-script clean-python-script
 clean-sh-script:
@@ -524,9 +530,9 @@ clean-perl-script:
 clean-python-script:
        $(RM) $(SCRIPT_PYTHON_GEN)
 
-SCRIPTS = $(SCRIPT_SH_GEN) \
-         $(SCRIPT_PERL_GEN) \
-         $(SCRIPT_PYTHON_GEN) \
+SCRIPTS = $(SCRIPT_SH_INS) \
+         $(SCRIPT_PERL_INS) \
+         $(SCRIPT_PYTHON_INS) \
          git-instaweb
 
 ETAGS_TARGET = TAGS
@@ -1672,7 +1678,7 @@ please_set_SHELL_PATH_to_a_more_modern_shell:
 shell_compatibility_test: please_set_SHELL_PATH_to_a_more_modern_shell
 
 strip: $(PROGRAMS) git$X
-       $(STRIP) $(STRIP_OPTS) $(PROGRAMS) git$X
+       $(STRIP) $(STRIP_OPTS) $^
 
 ### Target-specific flags and dependencies
 
@@ -1732,9 +1738,9 @@ version.sp version.s version.o: EXTRA_CPPFLAGS = \
 
 $(BUILT_INS): git$X
        $(QUIET_BUILT_IN)$(RM) $@ && \
-       ln git$X $@ 2>/dev/null || \
-       ln -s git$X $@ 2>/dev/null || \
-       cp git$X $@
+       ln $< $@ 2>/dev/null || \
+       ln -s $< $@ 2>/dev/null || \
+       cp $< $@
 
 common-cmds.h: ./generate-cmdlist.sh command-list.txt
 
@@ -1804,7 +1810,7 @@ $(patsubst %.perl,%,$(SCRIPT_PERL)): % : %.perl GIT-VERSION-FILE
            -e '        x' \
            -e '}' \
            -e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \
-           $@.perl >$@+ && \
+           $< >$@+ && \
        chmod +x $@+ && \
        mv $@+ $@
 
@@ -1828,8 +1834,8 @@ $(patsubst %.perl,%,$(SCRIPT_PERL)) git-instaweb: % : unimplemented.sh
 endif # NO_PERL
 
 ifndef NO_PYTHON
-$(patsubst %.py,%,$(SCRIPT_PYTHON)): GIT-CFLAGS GIT-PREFIX GIT-PYTHON-VARS
-$(patsubst %.py,%,$(SCRIPT_PYTHON)): % : %.py
+$(SCRIPT_PYTHON_GEN): GIT-CFLAGS GIT-PREFIX GIT-PYTHON-VARS
+$(SCRIPT_PYTHON_GEN): % : %.py
        $(QUIET_GEN)$(RM) $@ $@+ && \
        INSTLIBDIR=`MAKEFLAGS= $(MAKE) -C git_remote_helpers -s \
                --no-print-directory prefix='$(prefix_SQ)' DESTDIR='$(DESTDIR_SQ)' \
@@ -1837,11 +1843,11 @@ $(patsubst %.py,%,$(SCRIPT_PYTHON)): % : %.py
        sed -e '1s|#!.*python|#!$(PYTHON_PATH_SQ)|' \
            -e 's|\(os\.getenv("GITPYTHONLIB"\)[^)]*)|\1,"@@INSTLIBDIR@@")|' \
            -e 's|@@INSTLIBDIR@@|'"$$INSTLIBDIR"'|g' \
-           $@.py >$@+ && \
+           $< >$@+ && \
        chmod +x $@+ && \
        mv $@+ $@
 else # NO_PYTHON
-$(patsubst %.py,%,$(SCRIPT_PYTHON)): % : unimplemented.sh
+$(SCRIPT_PYTHON_GEN): % : unimplemented.sh
        $(QUIET_GEN)$(RM) $@ $@+ && \
        sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \
            -e 's|@@REASON@@|NO_PYTHON=$(NO_PYTHON)|g' \
index b2c4fe0e9f9816a6cb79aa8f7a0cb59ae5bf7f8d..4bde019bce632703d4e336d6404693487cdbcdfb 100644 (file)
@@ -232,7 +232,6 @@ static int write_zip_entry(struct archiver_args *args,
                size = 0;
                compressed_size = 0;
                buffer = NULL;
-               size = 0;
        } else if (S_ISREG(mode) || S_ISLNK(mode)) {
                enum object_type type = sha1_object_info(sha1, &size);
 
index faef55913634a21a757b4814f855ed834c32915e..64bab6bf54df4ae9e6e3695abb7bd5fd36ddfea6 100644 (file)
--- a/builtin.h
+++ b/builtin.h
@@ -12,6 +12,9 @@
 extern const char git_usage_string[];
 extern const char git_more_info_string[];
 
+#define PRUNE_PACKED_DRY_RUN 01
+#define PRUNE_PACKED_VERBOSE 02
+
 extern void prune_packed_objects(int);
 
 struct fmt_merge_msg_opts {
index b6ffc6b4feb2dc56d8239cbfcea7d6467a652e6d..66bff5700f1e33c009c69fc44ba327dff1acb135 100644 (file)
@@ -541,12 +541,18 @@ static void update_remote_refs(const struct ref *refs,
                               const struct ref *mapped_refs,
                               const struct ref *remote_head_points_at,
                               const char *branch_top,
-                              const char *msg)
+                              const char *msg,
+                              struct transport *transport)
 {
        const struct ref *rm = mapped_refs;
 
-       if (check_everything_connected(iterate_ref_map, 0, &rm))
+       if (0 <= option_verbosity)
+               printf(_("Checking connectivity... "));
+       if (check_everything_connected_with_transport(iterate_ref_map,
+                                                     0, &rm, transport))
                die(_("remote did not send all necessary objects"));
+       if (0 <= option_verbosity)
+               printf(_("done\n"));
 
        if (refs) {
                write_remote_refs(mapped_refs);
@@ -890,6 +896,9 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
                if (option_upload_pack)
                        transport_set_option(transport, TRANS_OPT_UPLOADPACK,
                                             option_upload_pack);
+
+               if (transport->smart_options && !option_depth)
+                       transport->smart_options->check_self_contained_and_connected = 1;
        }
 
        refs = transport_get_remote_refs(transport);
@@ -951,7 +960,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
                transport_fetch_refs(transport, mapped_refs);
 
        update_remote_refs(refs, mapped_refs, remote_head_points_at,
-                          branch_top.buf, reflog_msg.buf);
+                          branch_top.buf, reflog_msg.buf, transport);
 
        update_head(our_head_points_at, remote_head, reflog_msg.buf);
 
index d2f30d960a71e41da88d6cc4201cbdca168b8648..1621dfcd4008fc5853fc078a32bf9eefb6c52023 100644 (file)
@@ -107,7 +107,7 @@ static const char *cleanup_arg;
 
 static enum commit_whence whence;
 static int use_editor = 1, include_status = 1;
-static int show_ignored_in_status;
+static int show_ignored_in_status, have_option_m;
 static const char *only_include_assumed;
 static struct strbuf message = STRBUF_INIT;
 
@@ -121,9 +121,11 @@ static enum {
 static int opt_parse_m(const struct option *opt, const char *arg, int unset)
 {
        struct strbuf *buf = opt->value;
-       if (unset)
+       if (unset) {
+               have_option_m = 0;
                strbuf_setlen(buf, 0);
-       else {
+       } else {
+               have_option_m = 1;
                if (buf->len)
                        strbuf_addch(buf, '\n');
                strbuf_addstr(buf, arg);
@@ -975,7 +977,7 @@ static int parse_and_validate_options(int argc, const char *argv[],
        if (force_author && renew_authorship)
                die(_("Using both --reset-author and --author does not make sense"));
 
-       if (logfile || message.len || use_message || fixup_message)
+       if (logfile || have_option_m || use_message || fixup_message)
                use_editor = 0;
        if (0 <= edit_flag)
                use_editor = edit_flag;
index 79dfe47320e244c3110ce65d5b19fa87ebca3cb5..9c1cfac4427ef8d8fbca0834e1c8b644ceddf998 100644 (file)
@@ -77,8 +77,10 @@ static int nr_threads;
 
 static int from_stdin;
 static int strict;
+static int do_fsck_object;
 static int verbose;
 static int show_stat;
+static int check_self_contained_and_connected;
 
 static struct progress *progress;
 
@@ -187,13 +189,13 @@ static int mark_link(struct object *obj, int type, void *data)
 
 /* The content of each linked object must have been checked
    or it must be already present in the object database */
-static void check_object(struct object *obj)
+static unsigned check_object(struct object *obj)
 {
        if (!obj)
-               return;
+               return 0;
 
        if (!(obj->flags & FLAG_LINK))
-               return;
+               return 0;
 
        if (!(obj->flags & FLAG_CHECKED)) {
                unsigned long size;
@@ -201,17 +203,20 @@ static void check_object(struct object *obj)
                if (type != obj->type || type <= 0)
                        die(_("object of unexpected type"));
                obj->flags |= FLAG_CHECKED;
-               return;
+               return 1;
        }
+
+       return 0;
 }
 
-static void check_objects(void)
+static unsigned check_objects(void)
 {
-       unsigned i, max;
+       unsigned i, max, foreign_nr = 0;
 
        max = get_max_object_index();
        for (i = 0; i < max; i++)
-               check_object(get_indexed_object(i));
+               foreign_nr += check_object(get_indexed_object(i));
+       return foreign_nr;
 }
 
 
@@ -747,8 +752,7 @@ static void sha1_object(const void *data, struct object_entry *obj_entry,
                        int eaten;
                        void *buf = (void *) data;
 
-                       if (!buf)
-                               buf = new_data = get_data_from_pack(obj_entry);
+                       assert(data && "data can only be NULL for large _blobs_");
 
                        /*
                         * we do not need to free the memory here, as the
@@ -757,7 +761,8 @@ static void sha1_object(const void *data, struct object_entry *obj_entry,
                        obj = parse_object_buffer(sha1, type, size, buf, &eaten);
                        if (!obj)
                                die(_("invalid %s"), typename(type));
-                       if (fsck_object(obj, 1, fsck_error_function))
+                       if (do_fsck_object &&
+                           fsck_object(obj, 1, fsck_error_function))
                                die(_("Error in object"));
                        if (fsck_walk(obj, mark_link, NULL))
                                die(_("Not all child objects of %s are reachable"), sha1_to_hex(obj->sha1));
@@ -1491,6 +1496,7 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix)
        struct pack_idx_entry **idx_objects;
        struct pack_idx_option opts;
        unsigned char pack_sha1[20];
+       unsigned foreign_nr = 1;        /* zero is a "good" value, assume bad */
 
        if (argc == 2 && !strcmp(argv[1], "-h"))
                usage(index_pack_usage);
@@ -1512,6 +1518,10 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix)
                                fix_thin_pack = 1;
                        } else if (!strcmp(arg, "--strict")) {
                                strict = 1;
+                               do_fsck_object = 1;
+                       } else if (!strcmp(arg, "--check-self-contained-and-connected")) {
+                               strict = 1;
+                               check_self_contained_and_connected = 1;
                        } else if (!strcmp(arg, "--verify")) {
                                verify = 1;
                        } else if (!strcmp(arg, "--verify-stat")) {
@@ -1625,7 +1635,7 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix)
        conclude_pack(fix_thin_pack, curr_pack, pack_sha1);
        free(deltas);
        if (strict)
-               check_objects();
+               foreign_nr = check_objects();
 
        if (show_stat)
                show_pack_info(stat_only);
@@ -1651,5 +1661,11 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix)
        if (index_name == NULL)
                free((void *) curr_index);
 
+       /*
+        * Let the caller know this pack is not self contained
+        */
+       if (check_self_contained_and_connected && foreign_nr)
+               return 1;
+
        return 0;
 }
index 83382c1fe13e1f99aad4736993c08877c989a748..fa6ce42f44f82d34299f2dc0109be4d831cb3d48 100644 (file)
@@ -8,9 +8,6 @@ static const char * const prune_packed_usage[] = {
        NULL
 };
 
-#define DRY_RUN 01
-#define VERBOSE 02
-
 static struct progress *progress;
 
 static void prune_dir(int i, DIR *dir, char *pathname, int len, int opts)
@@ -29,7 +26,7 @@ static void prune_dir(int i, DIR *dir, char *pathname, int len, int opts)
                if (!has_sha1_pack(sha1))
                        continue;
                memcpy(pathname + len, de->d_name, 38);
-               if (opts & DRY_RUN)
+               if (opts & PRUNE_PACKED_DRY_RUN)
                        printf("rm -f %s\n", pathname);
                else
                        unlink_or_warn(pathname);
@@ -44,7 +41,7 @@ void prune_packed_objects(int opts)
        const char *dir = get_object_directory();
        int len = strlen(dir);
 
-       if (opts == VERBOSE)
+       if (opts & PRUNE_PACKED_VERBOSE)
                progress = start_progress_delay("Removing duplicate objects",
                        256, 95, 2);
 
@@ -71,10 +68,12 @@ void prune_packed_objects(int opts)
 
 int cmd_prune_packed(int argc, const char **argv, const char *prefix)
 {
-       int opts = isatty(2) ? VERBOSE : 0;
+       int opts = isatty(2) ? PRUNE_PACKED_VERBOSE : 0;
        const struct option prune_packed_options[] = {
-               OPT_BIT('n', "dry-run", &opts, N_("dry run"), DRY_RUN),
-               OPT_NEGBIT('q', "quiet", &opts, N_("be quiet"), VERBOSE),
+               OPT_BIT('n', "dry-run", &opts, N_("dry run"),
+                       PRUNE_PACKED_DRY_RUN),
+               OPT_NEGBIT('q', "quiet", &opts, N_("be quiet"),
+                          PRUNE_PACKED_VERBOSE),
                OPT_END()
        };
 
index b90e5cc361eb41064eaee242d8b13ceabe4335bc..6366917c6de55e171a7f697b22f1de10293addf5 100644 (file)
@@ -165,7 +165,7 @@ int cmd_prune(int argc, const char **argv, const char *prefix)
        stop_progress(&progress);
        prune_object_dir(get_object_directory());
 
-       prune_packed_objects(show_only);
+       prune_packed_objects(show_only ? PRUNE_PACKED_DRY_RUN : 0);
        remove_temporary_files(get_object_directory());
        s = mkpathdup("%s/pack", get_object_directory());
        remove_temporary_files(s);
index 909c34dfda984be86fba2013fedc3fdb10b5e2f1..2d84d10720fad88becdfe957f3770a2c44ac0a8f 100644 (file)
@@ -113,17 +113,19 @@ static NORETURN int die_push_simple(struct branch *branch, struct remote *remote
            remote->name, branch->name, advice_maybe);
 }
 
+static const char message_detached_head_die[] =
+       N_("You are not currently on a branch.\n"
+          "To push the history leading to the current (detached HEAD)\n"
+          "state now, use\n"
+          "\n"
+          "    git push %s HEAD:<name-of-remote-branch>\n");
+
 static void setup_push_upstream(struct remote *remote, int simple)
 {
        struct strbuf refspec = STRBUF_INIT;
        struct branch *branch = branch_get(NULL);
        if (!branch)
-               die(_("You are not currently on a branch.\n"
-                   "To push the history leading to the current (detached HEAD)\n"
-                   "state now, use\n"
-                   "\n"
-                   "    git push %s HEAD:<name-of-remote-branch>\n"),
-                   remote->name);
+               die(_(message_detached_head_die), remote->name);
        if (!branch->merge_nr || !branch->merge || !branch->remote_name)
                die(_("The current branch %s has no upstream branch.\n"
                    "To push the current branch and set the remote as upstream, use\n"
@@ -173,6 +175,8 @@ static void warn_unspecified_push_default_configuration(void)
 
 static void setup_default_push_refspecs(struct remote *remote)
 {
+       struct branch *branch;
+
        switch (push_default) {
        default:
        case PUSH_DEFAULT_UNSPECIFIED:
@@ -192,7 +196,10 @@ static void setup_default_push_refspecs(struct remote *remote)
                break;
 
        case PUSH_DEFAULT_CURRENT:
-               add_refspec("HEAD");
+               branch = branch_get(NULL);
+               if (!branch)
+                       die(_(message_detached_head_die), remote->name);
+               add_refspec(branch->name);
                break;
 
        case PUSH_DEFAULT_NOTHING:
index 67bd5091be0b34bfea075cd60281d22cf5b34768..6e9c7cd9d5da7d24d4810b36039681f184325932 100644 (file)
--- a/commit.h
+++ b/commit.h
@@ -176,6 +176,8 @@ extern int for_each_commit_graft(each_commit_graft_fn, void *);
 extern int is_repository_shallow(void);
 extern struct commit_list *get_shallow_commits(struct object_array *heads,
                int depth, int shallow_flag, int not_shallow_flag);
+extern void check_shallow_file_for_update(void);
+extern void set_alternate_shallow_file(const char *path);
 
 int is_descendant_of(struct commit *, struct commit_list *);
 int in_merge_bases(struct commit *, struct commit *);
index 830ee14b437ca74a3db9e56ea8cedff78b7964b6..7a85ebdbae79cf13305ebc821fafcd21a67c16d4 100644 (file)
--- a/config.c
+++ b/config.c
@@ -566,7 +566,20 @@ static int git_default_core_config(const char *var, const char *value)
                trust_ctime = git_config_bool(var, value);
                return 0;
        }
-       if (!strcmp(var, "core.statinfo")) {
+       if (!strcmp(var, "core.statinfo") ||
+           !strcmp(var, "core.checkstat")) {
+               /*
+                * NEEDSWORK: statinfo was a typo in v1.8.2 that has
+                * never been advertised.  we will remove it at Git
+                * 2.0 boundary.
+                */
+               if (!strcmp(var, "core.statinfo")) {
+                       static int warned;
+                       if (!warned++) {
+                               warning("'core.statinfo' will be removed in Git 2.0; "
+                                       "use 'core.checkstat' instead.");
+                       }
+               }
                if (!strcasecmp(value, "default"))
                        check_stat = 1;
                else if (!strcasecmp(value, "minimal"))
index 1e89c1cd1d63f160bf7c95de41be61ff2d888e70..fae8d64c12e44cf6bcf4bab210abc4bc4b9c8ed9 100644 (file)
@@ -2,7 +2,12 @@
 #include "run-command.h"
 #include "sigchain.h"
 #include "connected.h"
+#include "transport.h"
 
+int check_everything_connected(sha1_iterate_fn fn, int quiet, void *cb_data)
+{
+       return check_everything_connected_with_transport(fn, quiet, cb_data, NULL);
+}
 /*
  * If we feed all the commits we want to verify to this command
  *
  *
  * Returns 0 if everything is connected, non-zero otherwise.
  */
-int check_everything_connected(sha1_iterate_fn fn, int quiet, void *cb_data)
+int check_everything_connected_with_transport(sha1_iterate_fn fn,
+                                             int quiet,
+                                             void *cb_data,
+                                             struct transport *transport)
 {
        struct child_process rev_list;
        const char *argv[] = {"rev-list", "--objects",
@@ -22,10 +30,23 @@ int check_everything_connected(sha1_iterate_fn fn, int quiet, void *cb_data)
        char commit[41];
        unsigned char sha1[20];
        int err = 0;
+       struct packed_git *new_pack = NULL;
 
        if (fn(cb_data, sha1))
                return err;
 
+       if (transport && transport->smart_options &&
+           transport->smart_options->self_contained_and_connected &&
+           transport->pack_lockfile &&
+           !suffixcmp(transport->pack_lockfile, ".keep")) {
+               struct strbuf idx_file = STRBUF_INIT;
+               strbuf_addstr(&idx_file, transport->pack_lockfile);
+               strbuf_setlen(&idx_file, idx_file.len - 5); /* ".keep" */
+               strbuf_addstr(&idx_file, ".idx");
+               new_pack = add_packed_git(idx_file.buf, idx_file.len, 1);
+               strbuf_release(&idx_file);
+       }
+
        if (quiet)
                argv[5] = "--quiet";
 
@@ -42,6 +63,17 @@ int check_everything_connected(sha1_iterate_fn fn, int quiet, void *cb_data)
 
        commit[40] = '\n';
        do {
+               /*
+                * If index-pack already checked that:
+                * - there are no dangling pointers in the new pack
+                * - the pack is self contained
+                * Then if the updated ref is in the new pack, then we
+                * are sure the ref is good and not sending it to
+                * rev-list for verification.
+                */
+               if (new_pack && find_pack_entry_one(sha1, new_pack))
+                       continue;
+
                memcpy(commit, sha1_to_hex(sha1), 40);
                if (write_in_full(rev_list.in, commit, 41) < 0) {
                        if (errno != EPIPE && errno != EINVAL)
index 7e4585a6cbccdb35f4a4481fae1eaf417539e97d..0b060b7429ff2035ac3db108f80308c4a8a8e785 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef CONNECTED_H
 #define CONNECTED_H
 
+struct transport;
+
 /*
  * Take callback data, and return next object name in the buffer.
  * When called after returning the name for the last object, return -1
@@ -16,5 +18,8 @@ typedef int (*sha1_iterate_fn)(void *, unsigned char [20]);
  * Return 0 if Ok, non zero otherwise (i.e. some missing objects)
  */
 extern int check_everything_connected(sha1_iterate_fn, int quiet, void *cb_data);
+extern int check_everything_connected_with_transport(sha1_iterate_fn, int quiet,
+                                                    void *cb_data,
+                                                    struct transport *transport);
 
 #endif /* CONNECTED_H */
index eaf5c369aacde207cbad4c9df9574e7b26634bb7..86a4f3fa49cf68e14a6b0de13cb7f63fe8a2624d 100644 (file)
@@ -20,7 +20,8 @@
 #        <post>, which are strings you would put in $PS1 before
 #        and after the status string generated by the git-prompt
 #        machinery.  e.g.
-#           PROMPT_COMMAND='__git_ps1 "\u@\h:\w" "\\\$ "'
+#        Bash: PROMPT_COMMAND='__git_ps1 "\u@\h:\w" "\\\$ "'
+#        ZSH:  precmd () { __git_ps1 "%n" ":%~$ " "|%s" }
 #        will show username, at-sign, host, colon, cwd, then
 #        various status string, followed by dollar and SP, as
 #        your prompt.
@@ -124,7 +125,7 @@ __git_ps1_show_upstream ()
                        fi
                        ;;
                svn-remote.*.url)
-                       svn_remote[ $((${#svn_remote[@]} + 1)) ]="$value"
+                       svn_remote[$((${#svn_remote[@]} + 1))]="$value"
                        svn_url_pattern+="\\|$value"
                        upstream=svn+git # default upstream is SVN if available, else git
                        ;;
@@ -146,10 +147,11 @@ __git_ps1_show_upstream ()
        svn*)
                # get the upstream from the "git-svn-id: ..." in a commit message
                # (git-svn uses essentially the same procedure internally)
-               local svn_upstream=($(git log --first-parent -1 \
+               local -a svn_upstream
+               svn_upstream=($(git log --first-parent -1 \
                                        --grep="^git-svn-id: \(${svn_url_pattern#??}\)" 2>/dev/null))
                if [[ 0 -ne ${#svn_upstream[@]} ]]; then
-                       svn_upstream=${svn_upstream[ ${#svn_upstream[@]} - 2 ]}
+                       svn_upstream=${svn_upstream[${#svn_upstream[@]} - 2]}
                        svn_upstream=${svn_upstream%@*}
                        local n_stop="${#svn_remote[@]}"
                        for ((n=1; n <= n_stop; n++)); do
@@ -222,6 +224,85 @@ __git_ps1_show_upstream ()
 
 }
 
+# Helper function that is meant to be called from __git_ps1.  It
+# builds up a gitstring injecting color codes into the appropriate
+# places.
+__git_ps1_colorize_gitstring ()
+{
+       if [[ -n ${ZSH_VERSION-} ]]; then
+               local c_red='%F{red}'
+               local c_green='%F{green}'
+               local c_lblue='%F{blue}'
+               local c_clear='%f'
+               local bad_color=$c_red
+               local ok_color=$c_green
+               local branch_color="$c_clear"
+               local flags_color="$c_lblue"
+               local branchstring="$c${b##refs/heads/}"
+
+               if [ $detached = no ]; then
+                       branch_color="$ok_color"
+               else
+                       branch_color="$bad_color"
+               fi
+
+               gitstring="$branch_color$branchstring$c_clear"
+
+               if [ -n "$w$i$s$u$r$p" ]; then
+                       gitstring="$gitstring$z"
+               fi
+               if [ "$w" = "*" ]; then
+                       gitstring="$gitstring$bad_color$w"
+               fi
+               if [ -n "$i" ]; then
+                       gitstring="$gitstring$ok_color$i"
+               fi
+               if [ -n "$s" ]; then
+                       gitstring="$gitstring$flags_color$s"
+               fi
+               if [ -n "$u" ]; then
+                       gitstring="$gitstring$bad_color$u"
+               fi
+               gitstring="$gitstring$c_clear$r$p"
+               return
+       fi
+       local c_red='\e[31m'
+       local c_green='\e[32m'
+       local c_lblue='\e[1;34m'
+       local c_clear='\e[0m'
+       local bad_color=$c_red
+       local ok_color=$c_green
+       local branch_color="$c_clear"
+       local flags_color="$c_lblue"
+       local branchstring="$c${b##refs/heads/}"
+
+       if [ $detached = no ]; then
+               branch_color="$ok_color"
+       else
+               branch_color="$bad_color"
+       fi
+
+       # Setting gitstring directly with \[ and \] around colors
+       # is necessary to prevent wrapping issues!
+       gitstring="\[$branch_color\]$branchstring\[$c_clear\]"
+
+       if [ -n "$w$i$s$u$r$p" ]; then
+               gitstring="$gitstring$z"
+       fi
+       if [ "$w" = "*" ]; then
+               gitstring="$gitstring\[$bad_color\]$w"
+       fi
+       if [ -n "$i" ]; then
+               gitstring="$gitstring\[$ok_color\]$i"
+       fi
+       if [ -n "$s" ]; then
+               gitstring="$gitstring\[$flags_color\]$s"
+       fi
+       if [ -n "$u" ]; then
+               gitstring="$gitstring\[$bad_color\]$u"
+       fi
+       gitstring="$gitstring\[$c_clear\]$r$p"
+}
 
 # __git_ps1 accepts 0 or 1 arguments (i.e., format string)
 # when called from PS1 using command substitution
@@ -279,6 +360,7 @@ __git_ps1 ()
                                step=$(cat "$g/rebase-apply/next")
                                total=$(cat "$g/rebase-apply/last")
                                if [ -f "$g/rebase-apply/rebasing" ]; then
+                                       b="$(cat "$g/rebase-apply/head-name")"
                                        r="|REBASE"
                                elif [ -f "$g/rebase-apply/applying" ]; then
                                        r="|AM"
@@ -295,6 +377,7 @@ __git_ps1 ()
                                r="|BISECTING"
                        fi
 
+                       test -n "$b" ||
                        b="$(git symbolic-ref HEAD 2>/dev/null)" || {
                                detached=yes
                                b="$(
@@ -359,54 +442,20 @@ __git_ps1 ()
                        fi
                fi
 
+               local z="${GIT_PS1_STATESEPARATOR-" "}"
                local f="$w$i$s$u"
                if [ $pcmode = yes ]; then
                        local gitstring=
                        if [ -n "${GIT_PS1_SHOWCOLORHINTS-}" ]; then
-                               local c_red='\e[31m'
-                               local c_green='\e[32m'
-                               local c_lblue='\e[1;34m'
-                               local c_clear='\e[0m'
-                               local bad_color=$c_red
-                               local ok_color=$c_green
-                               local branch_color="$c_clear"
-                               local flags_color="$c_lblue"
-                               local branchstring="$c${b##refs/heads/}"
-
-                               if [ $detached = no ]; then
-                                       branch_color="$ok_color"
-                               else
-                                       branch_color="$bad_color"
-                               fi
-
-                               # Setting gitstring directly with \[ and \] around colors
-                               # is necessary to prevent wrapping issues!
-                               gitstring="\[$branch_color\]$branchstring\[$c_clear\]"
-
-                               if [ -n "$w$i$s$u$r$p" ]; then
-                                       gitstring="$gitstring "
-                               fi
-                               if [ "$w" = "*" ]; then
-                                       gitstring="$gitstring\[$bad_color\]$w"
-                               fi
-                               if [ -n "$i" ]; then
-                                       gitstring="$gitstring\[$ok_color\]$i"
-                               fi
-                               if [ -n "$s" ]; then
-                                       gitstring="$gitstring\[$flags_color\]$s"
-                               fi
-                               if [ -n "$u" ]; then
-                                       gitstring="$gitstring\[$bad_color\]$u"
-                               fi
-                               gitstring="$gitstring\[$c_clear\]$r$p"
+                               __git_ps1_colorize_gitstring
                        else
-                               gitstring="$c${b##refs/heads/}${f:+ $f}$r$p"
+                               gitstring="$c${b##refs/heads/}${f:+$z$f}$r$p"
                        fi
                        gitstring=$(printf -- "$printf_format" "$gitstring")
                        PS1="$ps1pc_start$gitstring$ps1pc_end"
                else
                        # NO color option unless in PROMPT_COMMAND mode
-                       printf -- "$printf_format" "$c${b##refs/heads/}${f:+ $f}$r$p"
+                       printf -- "$printf_format" "$c${b##refs/heads/}${f:+$z$f}$r$p"
                fi
        fi
 }
index 10daa8b0eb3352305347354d09ef443993af7809..51ae932e5edc54db32fca93e8f6f8aca1bea32f4 100755 (executable)
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/bin/sh
 #
 # git-subtree.sh: split/join git repositories in subdirectories of this one
 #
index f156dd4fac30cda4e09c508b7091cdb8d96917e2..abe5ffbba55037c34b1bf38a86aa0ec8bd7f3447 100644 (file)
@@ -20,6 +20,8 @@ static int no_done;
 static int fetch_fsck_objects = -1;
 static int transfer_fsck_objects = -1;
 static int agent_supported;
+static struct lock_file shallow_lock;
+static const char *alternate_shallow_file;
 
 #define COMPLETE       (1U << 0)
 #define COMMON         (1U << 1)
@@ -683,12 +685,13 @@ static int get_pack(struct fetch_pack_args *args,
                    int xd[2], char **pack_lockfile)
 {
        struct async demux;
-       const char *argv[20];
+       const char *argv[22];
        char keep_arg[256];
        char hdr_arg[256];
        const char **av;
        int do_keep = args->keep_pack;
        struct child_process cmd;
+       int ret;
 
        memset(&demux, 0, sizeof(demux));
        if (use_sideband) {
@@ -724,6 +727,11 @@ static int get_pack(struct fetch_pack_args *args,
                        do_keep = 1;
        }
 
+       if (alternate_shallow_file) {
+               *av++ = "--shallow-file";
+               *av++ = alternate_shallow_file;
+       }
+
        if (do_keep) {
                if (pack_lockfile)
                        cmd.out = -1;
@@ -740,11 +748,14 @@ static int get_pack(struct fetch_pack_args *args,
                                strcpy(keep_arg + s, "localhost");
                        *av++ = keep_arg;
                }
+               if (args->check_self_contained_and_connected)
+                       *av++ = "--check-self-contained-and-connected";
        }
        else {
                *av++ = "unpack-objects";
                if (args->quiet || args->no_progress)
                        *av++ = "-q";
+               args->check_self_contained_and_connected = 0;
        }
        if (*hdr_arg)
                *av++ = hdr_arg;
@@ -765,7 +776,12 @@ static int get_pack(struct fetch_pack_args *args,
                close(cmd.out);
        }
 
-       if (finish_command(&cmd))
+       ret = finish_command(&cmd);
+       if (!ret || (args->check_self_contained_and_connected && ret == 1))
+               args->self_contained_and_connected =
+                       args->check_self_contained_and_connected &&
+                       ret == 0;
+       else
                die("%s failed", argv[0]);
        if (use_sideband && finish_async(&demux))
                die("error in sideband demultiplexer");
@@ -779,6 +795,27 @@ static int cmp_ref_by_name(const void *a_, const void *b_)
        return strcmp(a->name, b->name);
 }
 
+static void setup_alternate_shallow(void)
+{
+       struct strbuf sb = STRBUF_INIT;
+       int fd;
+
+       check_shallow_file_for_update();
+       fd = hold_lock_file_for_update(&shallow_lock, git_path("shallow"),
+                                      LOCK_DIE_ON_ERROR);
+       if (write_shallow_commits(&sb, 0)) {
+               if (write_in_full(fd, sb.buf, sb.len) != sb.len)
+                       die_errno("failed to write to %s", shallow_lock.filename);
+               alternate_shallow_file = shallow_lock.filename;
+       } else
+               /*
+                * is_repository_shallow() sees empty string as "no
+                * shallow file".
+                */
+               alternate_shallow_file = "";
+       strbuf_release(&sb);
+}
+
 static struct ref *do_fetch_pack(struct fetch_pack_args *args,
                                 int fd[2],
                                 const struct ref *orig_ref,
@@ -858,6 +895,8 @@ static struct ref *do_fetch_pack(struct fetch_pack_args *args,
 
        if (args->stateless_rpc)
                packet_flush(fd[1]);
+       if (args->depth > 0)
+               setup_alternate_shallow();
        if (get_pack(args, fd, pack_lockfile))
                die("git fetch-pack: fetch failed.");
 
@@ -936,15 +975,9 @@ struct ref *fetch_pack(struct fetch_pack_args *args,
                       struct ref **sought, int nr_sought,
                       char **pack_lockfile)
 {
-       struct stat st;
        struct ref *ref_cpy;
 
        fetch_pack_setup();
-       if (args->depth > 0) {
-               if (stat(git_path("shallow"), &st))
-                       st.st_mtime = 0;
-       }
-
        if (nr_sought)
                nr_sought = remove_duplicates_in_refs(sought, nr_sought);
 
@@ -954,35 +987,12 @@ struct ref *fetch_pack(struct fetch_pack_args *args,
        }
        ref_cpy = do_fetch_pack(args, fd, ref, sought, nr_sought, pack_lockfile);
 
-       if (args->depth > 0) {
-               static struct lock_file lock;
-               struct cache_time mtime;
-               struct strbuf sb = STRBUF_INIT;
-               char *shallow = git_path("shallow");
-               int fd;
-
-               mtime.sec = st.st_mtime;
-               mtime.nsec = ST_MTIME_NSEC(st);
-               if (stat(shallow, &st)) {
-                       if (mtime.sec)
-                               die("shallow file was removed during fetch");
-               } else if (st.st_mtime != mtime.sec
-#ifdef USE_NSEC
-                               || ST_MTIME_NSEC(st) != mtime.nsec
-#endif
-                         )
-                       die("shallow file was changed during fetch");
-
-               fd = hold_lock_file_for_update(&lock, shallow,
-                                              LOCK_DIE_ON_ERROR);
-               if (!write_shallow_commits(&sb, 0)
-                || write_in_full(fd, sb.buf, sb.len) != sb.len) {
-                       unlink_or_warn(shallow);
-                       rollback_lock_file(&lock);
-               } else {
-                       commit_lock_file(&lock);
-               }
-               strbuf_release(&sb);
+       if (alternate_shallow_file) {
+               if (*alternate_shallow_file == '\0') { /* --unshallow */
+                       unlink_or_warn(git_path("shallow"));
+                       rollback_lock_file(&shallow_lock);
+               } else
+                       commit_lock_file(&shallow_lock);
        }
 
        reprepare_packed_git();
index dc5266c970655a9fe4f971a0132c14e1cf731acc..40f08bab24df917986de73c8d7f4d9d36fe658da 100644 (file)
@@ -16,7 +16,9 @@ struct fetch_pack_args {
                verbose:1,
                no_progress:1,
                include_tag:1,
-               stateless_rpc:1;
+               stateless_rpc:1,
+               check_self_contained_and_connected:1,
+               self_contained_and_connected:1;
 };
 
 /*
index d7518e9c3b2cdf16da10b791a0591dc2347fd168..9f064b6f4f0c209a0315538e48049c2d013316df 100755 (executable)
@@ -320,8 +320,8 @@ bisect_next() {
        elif test $res -eq 2
        then
                echo "# only skipped commits left to test" >>"$GIT_DIR/BISECT_LOG"
-               good_revs=$(git for-each-ref --format="--not %(objectname)" "refs/bisect/good-*")
-               for skipped in $(git rev-list refs/bisect/bad $good_revs)
+               good_revs=$(git for-each-ref --format="%(objectname)" "refs/bisect/good-*")
+               for skipped in $(git rev-list refs/bisect/bad --not $good_revs)
                do
                        skipped_commit=$(git show-branch $skipped)
                        echo "# possible first bad commit: $skipped_commit" >>"$GIT_DIR/BISECT_LOG"
index 660b7f012ac8a94a25da818c0ec6667ff3378add..aa0404ef418410905c3dfa7c88a8700cf41c6110 100644 (file)
 #else
 #include <poll.h>
 #endif
+
+extern int get_st_mode_bits(const char *path, int *mode);
+
 #if defined(__MINGW32__)
 /* pull in Windows compatibility stuff */
 #include "compat/mingw.h"
 typedef long intptr_t;
 typedef unsigned long uintptr_t;
 #endif
-int get_st_mode_bits(const char *path, int *mode);
 #if defined(__CYGWIN__)
 #undef _XOPEN_SOURCE
 #include <grp.h>
index 8a7520553776ec9d0c8d38526041dd37742d3bc1..e57d3d1295a5ba0a9c02c19df512c909a0631baa 100755 (executable)
@@ -85,13 +85,9 @@ sub exit_cleanup
 
 sub use_wt_file
 {
-       my ($repo, $workdir, $file, $sha1, $symlinks) = @_;
+       my ($repo, $workdir, $file, $sha1) = @_;
        my $null_sha1 = '0' x 40;
 
-       if ($sha1 ne $null_sha1 and not $symlinks) {
-               return 0;
-       }
-
        if (! -e "$workdir/$file") {
                # If the file doesn't exist in the working tree, we cannot
                # use it.
@@ -213,8 +209,7 @@ sub setup_dir_diff
 
                if ($rmode ne $null_mode) {
                        my ($use, $wt_sha1) = use_wt_file($repo, $workdir,
-                                                         $dst_path, $rsha1,
-                                                         $symlinks);
+                                                         $dst_path, $rsha1);
                        if ($use) {
                                push @working_tree, $dst_path;
                                $wtindex .= "$rmode $wt_sha1\t$dst_path\0";
index bd13cc812d2a0115edcdd2c3ec146665ddfc5e29..ec1d6ce4ebfd4810d46c727e99af9a1b54074ec4 100755 (executable)
@@ -203,11 +203,9 @@ sub do_edit {
 
 my ($debug_net_smtp) = 0;              # Net::SMTP, see send_message()
 
-my $not_set_by_user = "true but not set by the user";
-
 my %config_bool_settings = (
     "thread" => [\$thread, 1],
-    "chainreplyto" => [\$chain_reply_to, $not_set_by_user],
+    "chainreplyto" => [\$chain_reply_to, 0],
     "suppressfrom" => [\$suppress_from, undef],
     "signedoffbycc" => [\$signed_off_by_cc, undef],
     "signedoffcc" => [\$signed_off_by_cc, undef],      # Deprecated
@@ -241,19 +239,6 @@ sub do_edit {
     "aliasesfile" => \@alias_files,
 );
 
-# Help users prepare for 1.7.0
-sub chain_reply_to {
-       if (defined $chain_reply_to &&
-           $chain_reply_to eq $not_set_by_user) {
-               print STDERR
-                   "In git 1.7.0, the default has changed to --no-chain-reply-to\n" .
-                   "Set sendemail.chainreplyto configuration variable to true if\n" .
-                   "you want to keep --chain-reply-to as your default.\n";
-               $chain_reply_to = 0;
-       }
-       return $chain_reply_to;
-}
-
 # Handle Uncouth Termination
 sub signal_handler {
 
@@ -1437,7 +1422,7 @@ sub send_message {
 
        # set up for the next message
        if ($thread && $message_was_sent &&
-               (chain_reply_to() || !defined $reply_to || length($reply_to) == 0 ||
+               ($chain_reply_to || !defined $reply_to || length($reply_to) == 0 ||
                $message_num == 1)) {
                $reply_to = $message_id;
                if (length $references > 0) {
diff --git a/git.c b/git.c
index 7dd07aae7a13aca1c910d6f126495e8280d00a71..4359086fd6c47f1bfc3fc408b7bc986517eea9a0 100644 (file)
--- a/git.c
+++ b/git.c
@@ -4,6 +4,7 @@
 #include "help.h"
 #include "quote.h"
 #include "run-command.h"
+#include "commit.h"
 
 const char git_usage_string[] =
        "git [--version] [--help] [-c name=value]\n"
@@ -146,6 +147,12 @@ static int handle_options(const char ***argv, int *argc, int *envchanged)
                        setenv(GIT_LITERAL_PATHSPECS_ENVIRONMENT, "0", 1);
                        if (envchanged)
                                *envchanged = 1;
+               } else if (!strcmp(cmd, "--shallow-file")) {
+                       (*argv)++;
+                       (*argc)--;
+                       set_alternate_shallow_file((*argv)[0]);
+                       if (envchanged)
+                               *envchanged = 1;
                } else {
                        fprintf(stderr, "Unknown option: %s\n", cmd);
                        usage(git_usage_string);
index 68eb99bdf0ca3fedd02ab1bc93db7549b21b62d4..e71f66de25b6031bbe1ee94ab3770aacd15b46e0 100644 (file)
--- a/remote.c
+++ b/remote.c
@@ -1474,8 +1474,7 @@ struct branch *branch_get(const char *name)
                ret->remote = remote_get(ret->remote_name);
                if (ret->merge_nr) {
                        int i;
-                       ret->merge = xcalloc(sizeof(*ret->merge),
-                                            ret->merge_nr);
+                       ret->merge = xcalloc(ret->merge_nr, sizeof(*ret->merge));
                        for (i = 0; i < ret->merge_nr; i++) {
                                ret->merge[i] = xcalloc(1, sizeof(**ret->merge));
                                ret->merge[i]->src = xstrdup(ret->merge_name[i]);
index 6be915f38f1fe8dbe0a22c4cd8ae2569331f483f..cbe2526d8c2b2643957eea2729a16269a7a74fab 100644 (file)
--- a/shallow.c
+++ b/shallow.c
@@ -3,6 +3,16 @@
 #include "tag.h"
 
 static int is_shallow = -1;
+static struct stat shallow_stat;
+static char *alternate_shallow_file;
+
+void set_alternate_shallow_file(const char *path)
+{
+       if (is_shallow != -1)
+               die("BUG: is_repository_shallow must not be called before set_alternate_shallow_file");
+       free(alternate_shallow_file);
+       alternate_shallow_file = path ? xstrdup(path) : NULL;
+}
 
 int register_shallow(const unsigned char *sha1)
 {
@@ -21,12 +31,21 @@ int is_repository_shallow(void)
 {
        FILE *fp;
        char buf[1024];
+       const char *path = alternate_shallow_file;
 
        if (is_shallow >= 0)
                return is_shallow;
 
-       fp = fopen(git_path("shallow"), "r");
-       if (!fp) {
+       if (!path)
+               path = git_path("shallow");
+       /*
+        * fetch-pack sets '--shallow-file ""' as an indicator that no
+        * shallow file should be used. We could just open it and it
+        * will likely fail. But let's do an explicit check instead.
+        */
+       if (!*path ||
+           stat(path, &shallow_stat) ||
+           (fp = fopen(path, "r")) == NULL) {
                is_shallow = 0;
                return is_shallow;
        }
@@ -108,3 +127,22 @@ struct commit_list *get_shallow_commits(struct object_array *heads, int depth,
 
        return result;
 }
+
+void check_shallow_file_for_update(void)
+{
+       struct stat st;
+
+       if (!is_shallow)
+               return;
+       else if (is_shallow == -1)
+               die("BUG: shallow must be initialized by now");
+
+       if (stat(git_path("shallow"), &st))
+               die("shallow file was removed during fetch");
+       else if (st.st_mtime != shallow_stat.st_mtime
+#ifdef USE_NSEC
+                || ST_MTIME_NSEC(st) != ST_MTIME_NSEC(shallow_stat)
+#endif
+                  )
+               die("shallow file was changed during fetch");
+}
index e669bb31b9aa2513a6f71de9fd066a21a0a3bde7..35b3c5c2faec0ed543dde460a30de63c48e5f1e7 100644 (file)
--- a/t/README
+++ b/t/README
@@ -324,6 +324,9 @@ Don't:
    use 'test_must_fail git cmd'.  This will signal a failure if git
    dies in an unexpected way (e.g. segfault).
 
+   On the other hand, don't use test_must_fail for running regular
+   platform commands; just use '! cmd'.
+
  - use perl without spelling it as "$PERL_PATH". This is to help our
    friends on Windows where the platform Perl often adds CR before
    the end of line, and they bundle Git with a version of Perl that
index 826500bd18a520a37e3490b9deeca94fb9e14405..3968020e648091e907fde6efe9aeb5ce66753670 100755 (executable)
@@ -64,10 +64,11 @@ test_expect_success 'rebase with --merge' '
 
 test_expect_success 'rebase --skip with --merge' '
        git rebase --skip
-       '
+'
 
-test_expect_success 'merge and reference trees equal' \
-       'test -z "`git diff-tree skip-merge skip-reference`"'
+test_expect_success 'merge and reference trees equal' '
+       test -z "`git diff-tree skip-merge skip-reference`"
+'
 
 test_expect_success 'moved back to branch correctly' '
        test refs/heads/skip-merge = $(git symbolic-ref HEAD)
index a58406d12fc8dabf8f2e73e721d2f622a781cc9a..79e8d3c5966bad34b317c6e35c301ecfaa3ab648 100755 (executable)
@@ -692,7 +692,7 @@ test_expect_success 'rebase -i can copy notes' '
        test_commit n2 &&
        test_commit n3 &&
        git notes add -m"a note" n3 &&
-       git rebase --onto n1 n2 &&
+       git rebase -i --onto n1 n2 &&
        test "a note" = "$(git notes show HEAD)"
 '
 
index a0c6e30d805e6e71b9fec4311a6ede298b6265b4..fbdc47cfbdae6e3cec7d6762faa4a8e13554d803 100755 (executable)
@@ -28,29 +28,21 @@ test_expect_success setup '
 '
 
 test_expect_success 'cherry-pick an empty commit' '
-       git checkout master && {
-               git cherry-pick empty-branch^
-               test "$?" = 1
-       }
+       git checkout master &&
+       test_expect_code 1 git cherry-pick empty-branch^
 '
 
 test_expect_success 'index lockfile was removed' '
-
        test ! -f .git/index.lock
-
 '
 
 test_expect_success 'cherry-pick a commit with an empty message' '
-       git checkout master && {
-               git cherry-pick empty-branch
-               test "$?" = 1
-       }
+       git checkout master &&
+       test_expect_code 1 git cherry-pick empty-branch
 '
 
 test_expect_success 'index lockfile was removed' '
-
        test ! -f .git/index.lock
-
 '
 
 test_expect_success 'cherry-pick a commit with an empty message with --allow-empty-message' '
@@ -101,7 +93,7 @@ test_expect_success 'cherry-pick a no-op with --keep-redundant' '
        git reset --hard &&
        git checkout fork^0 &&
        git cherry-pick --keep-redundant-commits master &&
-       git show -s --format='%s' >actual &&
+       git show -s --format=%s >actual &&
        echo "add file2 on master" >expect &&
        test_cmp expect actual
 '
index 6133d9ed13804d1cda4044e906ada1065fbad4a6..fd2598e60190fe04381652c7dfe997e01b4ea0c5 100755 (executable)
@@ -135,6 +135,13 @@ test_expect_success 'clone shallow depth 1' '
        test "`git --git-dir=shallow0/.git rev-list --count HEAD`" = 1
 '
 
+test_expect_success 'clone shallow depth 1 with fsck' '
+       git config --global fetch.fsckobjects true &&
+       git clone --no-single-branch --depth 1 "file://$(pwd)/." shallow0fsck &&
+       test "`git --git-dir=shallow0fsck/.git rev-list --count HEAD`" = 1 &&
+       git config --global --unset fetch.fsckobjects
+'
+
 test_expect_success 'clone shallow' '
        git clone --no-single-branch --depth 2 "file://$(pwd)/." shallow
 '
index a4938b1e4549d5082362ec3f5513ffe91f210d39..6313da2cdd979c6264e7a255711c6e444b768b96 100755 (executable)
@@ -361,6 +361,23 @@ test_expect_success !AUTOIDENT 'do not fire editor when committer is bogus' '
        test_cmp expect .git/result
 '
 
+test_expect_success 'do not fire editor if -m <msg> was given' '
+       echo tick >file &&
+       git add file &&
+       echo "editor not started" >.git/result &&
+       (GIT_EDITOR="\"$(pwd)/.git/FAKE_EDITOR\"" git commit -m tick) &&
+       test "$(cat .git/result)" = "editor not started"
+'
+
+test_expect_success 'do not fire editor if -m "" was given' '
+       echo tock >file &&
+       git add file &&
+       echo "editor not started" >.git/result &&
+       (GIT_EDITOR="\"$(pwd)/.git/FAKE_EDITOR\"" \
+        git commit -m "" --allow-empty-message) &&
+       test "$(cat .git/result)" = "editor not started"
+'
+
 test_expect_success 'do not fire editor in the presence of conflicts' '
 
        git clean -f &&
index d46f0411bd9a08b38035c8fb5ca611723b8baed2..2418528487624bf5497af71c9958a84e0a50328f 100755 (executable)
@@ -385,6 +385,25 @@ test_expect_success PERL,SYMLINKS 'difftool --dir-diff --symlink without unstage
        test_cmp actual expect
 '
 
+write_script modify-right-file <<\EOF
+echo "new content" >"$2/file"
+EOF
+
+run_dir_diff_test 'difftool --dir-diff syncs worktree with unstaged change' '
+       test_when_finished git reset --hard &&
+       echo "orig content" >file &&
+       git difftool -d $symlinks --extcmd "$(pwd)/modify-right-file" branch &&
+       echo "new content" >expect &&
+       test_cmp expect file
+'
+
+run_dir_diff_test 'difftool --dir-diff syncs worktree without unstaged change' '
+       test_when_finished git reset --hard &&
+       git difftool -d $symlinks --extcmd "$(pwd)/modify-right-file" branch &&
+       echo "new content" >expect &&
+       test_cmp expect file
+'
+
 write_script modify-file <<\EOF
 echo "new content" >file
 EOF
index ebd5c5db45c8816f39b2d8c60775f455ab9c48aa..5d2dbe98d5e01e8b18b5d9fe26ce5ed6f2bf171d 100755 (executable)
@@ -1003,55 +1003,6 @@ test_expect_success $PREREQ 'threading but no chain-reply-to' '
        grep "In-Reply-To: " stdout
 '
 
-test_expect_success $PREREQ 'warning with an implicit --chain-reply-to' '
-       git send-email \
-       --dry-run \
-       --from="Example <nobody@example.com>" \
-       --to=nobody@example.com \
-       outdir/000?-*.patch 2>errors >out &&
-       grep "no-chain-reply-to" errors
-'
-
-test_expect_success $PREREQ 'no warning with an explicit --chain-reply-to' '
-       git send-email \
-       --dry-run \
-       --from="Example <nobody@example.com>" \
-       --to=nobody@example.com \
-       --chain-reply-to \
-       outdir/000?-*.patch 2>errors >out &&
-       ! grep "no-chain-reply-to" errors
-'
-
-test_expect_success $PREREQ 'no warning with an explicit --no-chain-reply-to' '
-       git send-email \
-       --dry-run \
-       --from="Example <nobody@example.com>" \
-       --to=nobody@example.com \
-       --nochain-reply-to \
-       outdir/000?-*.patch 2>errors >out &&
-       ! grep "no-chain-reply-to" errors
-'
-
-test_expect_success $PREREQ 'no warning with sendemail.chainreplyto = false' '
-       git config sendemail.chainreplyto false &&
-       git send-email \
-       --dry-run \
-       --from="Example <nobody@example.com>" \
-       --to=nobody@example.com \
-       outdir/000?-*.patch 2>errors >out &&
-       ! grep "no-chain-reply-to" errors
-'
-
-test_expect_success $PREREQ 'no warning with sendemail.chainreplyto = true' '
-       git config sendemail.chainreplyto true &&
-       git send-email \
-       --dry-run \
-       --from="Example <nobody@example.com>" \
-       --to=nobody@example.com \
-       outdir/000?-*.patch 2>errors >out &&
-       ! grep "no-chain-reply-to" errors
-'
-
 test_expect_success $PREREQ 'sendemail.to works' '
        git config --replace-all sendemail.to "Somebody <somebody@ex.com>" &&
        git send-email \
index 083b319ed11132ae03c1f653f1ba13149f5a1ebe..15521cc4f9be68ccd105916cee1322041682e8d5 100755 (executable)
@@ -276,7 +276,7 @@ test_expect_success 'prompt - rebase merge' '
 '
 
 test_expect_success 'prompt - rebase' '
-       printf " ((t2)|REBASE 1/3)" > expected &&
+       printf " (b2|REBASE 1/3)" > expected &&
        git checkout b2 &&
        test_when_finished "git checkout master" &&
        test_must_fail git rebase b1 b2 &&
index 2f5ac3fbeefd65c61c9e9c89f97896f9dfac89c5..06c08a1786391e7a04fa566af0cf42c659ed8aa9 100644 (file)
@@ -809,6 +809,11 @@ static int push_refs_with_export(struct transport *transport,
        if (!data->refspecs)
                die("remote-helper doesn't support push; refspec needed");
 
+       if (flags & TRANSPORT_PUSH_DRY_RUN) {
+               if (set_helper_option(transport, "dry-run", "true") != 0)
+                       die("helper %s does not support dry-run", data->name);
+       }
+
        helper = get_helper(transport);
 
        write_constant(helper->in, "export\n");
@@ -830,8 +835,14 @@ static int push_refs_with_export(struct transport *transport,
                }
                free(private);
 
-               if (ref->peer_ref)
+               if (ref->deletion)
+                       die("remote-helpers do not support ref deletion");
+
+               if (ref->peer_ref) {
+                       if (strcmp(ref->peer_ref->name, ref->name))
+                               die("remote-helpers do not support old:new syntax");
                        string_list_append(&revlist_args, ref->peer_ref->name);
+               }
        }
 
        if (get_exporter(transport, &exporter, &revlist_args))
index ba5d8afb1b04ba9d331c721fd9f730184fff2f23..359a671c8ca9232944cd6e92a2ac0a9eda7b429d 100644 (file)
@@ -534,6 +534,8 @@ static int fetch_refs_via_pack(struct transport *transport,
        args.quiet = (transport->verbose < 0);
        args.no_progress = !transport->progress;
        args.depth = data->options.depth;
+       args.check_self_contained_and_connected =
+               data->options.check_self_contained_and_connected;
 
        if (!data->got_remote_heads) {
                connect_setup(transport, 0, 0);
@@ -551,6 +553,8 @@ static int fetch_refs_via_pack(struct transport *transport,
                refs = NULL;
        data->conn = NULL;
        data->got_remote_heads = 0;
+       data->options.self_contained_and_connected =
+               args.self_contained_and_connected;
 
        free_refs(refs_tmp);
 
index fcb1d25d96a750c171c4341a9c5f08992915fb6b..4edebc535583f655cc120d169677ea221af554b3 100644 (file)
@@ -8,6 +8,8 @@ struct git_transport_options {
        unsigned thin : 1;
        unsigned keep : 1;
        unsigned followtags : 1;
+       unsigned check_self_contained_and_connected : 1;
+       unsigned self_contained_and_connected : 1;
        int depth;
        const char *uploadpack;
        const char *receivepack;