mirror of
https://github.com/git/git.git
synced 2026-03-14 02:43:25 +01:00
Merge commit '77e6f5bc1009aa588a3b2235758bf5be13b23d85'
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,4 +1,5 @@
|
||||
GIT-CFLAGS
|
||||
GIT-GUI-VARS
|
||||
GIT-VERSION-FILE
|
||||
git
|
||||
git-add
|
||||
@@ -141,6 +142,7 @@ git-verify-tag
|
||||
git-whatchanged
|
||||
git-write-tree
|
||||
git-core-*/?*
|
||||
gitk-wish
|
||||
gitweb/gitweb.cgi
|
||||
test-chmtime
|
||||
test-date
|
||||
|
||||
@@ -65,6 +65,11 @@ install: man
|
||||
$(INSTALL) -m644 $(DOC_MAN7) $(DESTDIR)$(man7dir)
|
||||
|
||||
|
||||
../GIT-VERSION-FILE: .FORCE-GIT-VERSION-FILE
|
||||
$(MAKE) -C ../ GIT-VERSION-FILE
|
||||
|
||||
-include ../GIT-VERSION-FILE
|
||||
|
||||
#
|
||||
# Determine "include::" file references in asciidoc files.
|
||||
#
|
||||
@@ -91,17 +96,25 @@ $(cmds_txt): cmd-list.perl $(MAN1_TXT)
|
||||
git.7 git.html: git.txt core-intro.txt
|
||||
|
||||
clean:
|
||||
rm -f *.xml *.html *.1 *.7 howto-index.txt howto/*.html doc.dep
|
||||
rm -f *.xml *.xml+ *.html *.html+ *.1 *.7 howto-index.txt howto/*.html doc.dep
|
||||
rm -f $(cmds_txt)
|
||||
|
||||
%.html : %.txt
|
||||
$(ASCIIDOC) -b xhtml11 -d manpage -f asciidoc.conf $(ASCIIDOC_EXTRA) $<
|
||||
rm -f $@+ $@
|
||||
$(ASCIIDOC) -b xhtml11 -d manpage -f asciidoc.conf \
|
||||
$(ASCIIDOC_EXTRA) -o - $< | \
|
||||
sed -e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' >$@+
|
||||
mv $@+ $@
|
||||
|
||||
%.1 %.7 : %.xml
|
||||
xmlto -m callouts.xsl man $<
|
||||
|
||||
%.xml : %.txt
|
||||
$(ASCIIDOC) -b docbook -d manpage -f asciidoc.conf $<
|
||||
rm -f $@+ $@
|
||||
$(ASCIIDOC) -b docbook -d manpage -f asciidoc.conf \
|
||||
$(ASCIIDOC_EXTRA) -o - $< | \
|
||||
sed -e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' >$@+
|
||||
mv $@+ $@
|
||||
|
||||
user-manual.xml: user-manual.txt user-manual.conf
|
||||
$(ASCIIDOC) -b docbook -d book $<
|
||||
@@ -132,3 +145,5 @@ install-webdoc : html
|
||||
|
||||
quick-install:
|
||||
sh ./install-doc-quick.sh $(DOC_REF) $(mandir)
|
||||
|
||||
.PHONY: .FORCE-GIT-VERSION-FILE
|
||||
|
||||
@@ -31,6 +31,25 @@ ifdef::backend-docbook[]
|
||||
{title#}</example>
|
||||
endif::backend-docbook[]
|
||||
|
||||
ifdef::doctype-manpage[]
|
||||
ifdef::backend-docbook[]
|
||||
[header]
|
||||
template::[header-declarations]
|
||||
<refentry>
|
||||
<refmeta>
|
||||
<refentrytitle>{mantitle}</refentrytitle>
|
||||
<manvolnum>{manvolnum}</manvolnum>
|
||||
<refmiscinfo class="source">Git</refmiscinfo>
|
||||
<refmiscinfo class="version">@@GIT_VERSION@@</refmiscinfo>
|
||||
<refmiscinfo class="manual">Git Manual</refmiscinfo>
|
||||
</refmeta>
|
||||
<refnamediv>
|
||||
<refname>{manname}</refname>
|
||||
<refpurpose>{manpurpose}</refpurpose>
|
||||
</refnamediv>
|
||||
endif::backend-docbook[]
|
||||
endif::doctype-manpage[]
|
||||
|
||||
ifdef::backend-xhtml11[]
|
||||
[gitlink-inlinemacro]
|
||||
<a href="{target}.html">{target}{0?({0})}</a>
|
||||
|
||||
@@ -9,7 +9,7 @@ git-fsck - Verifies the connectivity and validity of the objects in the database
|
||||
SYNOPSIS
|
||||
--------
|
||||
[verse]
|
||||
'git-fsck' [--tags] [--root] [--unreachable] [--cache]
|
||||
'git-fsck' [--tags] [--root] [--unreachable] [--cache] [--no-reflogs]
|
||||
[--full] [--strict] [<object>*]
|
||||
|
||||
DESCRIPTION
|
||||
@@ -38,6 +38,12 @@ index file and all SHA1 references in .git/refs/* as heads.
|
||||
Consider any object recorded in the index also as a head node for
|
||||
an unreachability trace.
|
||||
|
||||
--no-reflogs::
|
||||
Do not consider commits that are referenced only by an
|
||||
entry in a reflog to be reachable. This option is meant
|
||||
only to search for commits that used to be in a ref, but
|
||||
now aren't, but are still in that corresponding reflog.
|
||||
|
||||
--full::
|
||||
Check not just objects in GIT_OBJECT_DIRECTORY
|
||||
($GIT_DIR/objects), but also the ones found in alternate
|
||||
|
||||
@@ -21,11 +21,13 @@ SYNOPSIS
|
||||
[ \--stdin ]
|
||||
[ \--topo-order ]
|
||||
[ \--parents ]
|
||||
[ \--left-right ]
|
||||
[ \--encoding[=<encoding>] ]
|
||||
[ \--(author|committer|grep)=<pattern> ]
|
||||
[ [\--objects | \--objects-edge] [ \--unpacked ] ]
|
||||
[ \--pretty | \--header ]
|
||||
[ \--bisect ]
|
||||
[ \--bisect-vars ]
|
||||
[ \--merge ]
|
||||
[ \--reverse ]
|
||||
[ \--walk-reflogs ]
|
||||
@@ -100,6 +102,36 @@ include::pretty-formats.txt[]
|
||||
|
||||
Print the parents of the commit.
|
||||
|
||||
--left-right::
|
||||
|
||||
Mark which side of a symmetric diff a commit is reachable from.
|
||||
Commits from the left side are prefixed with `<` and those from
|
||||
the right with `>`. If combined with `--boundary`, those
|
||||
commits are prefixed with `-`.
|
||||
+
|
||||
For example, if you have this topology:
|
||||
+
|
||||
-----------------------------------------------------------------------
|
||||
y---b---b branch B
|
||||
/ \ /
|
||||
/ .
|
||||
/ / \
|
||||
o---x---a---a branch A
|
||||
-----------------------------------------------------------------------
|
||||
+
|
||||
you would get an output line this:
|
||||
+
|
||||
-----------------------------------------------------------------------
|
||||
$ git rev-list --left-right --boundary --pretty=oneline A...B
|
||||
|
||||
>bbbbbbb... 3rd on b
|
||||
>bbbbbbb... 2nd on b
|
||||
<aaaaaaa... 3rd on a
|
||||
<aaaaaaa... 2nd on a
|
||||
-yyyyyyy... 1st on b
|
||||
-xxxxxxx... 1st on a
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
Diff Formatting
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
@@ -249,6 +281,18 @@ introduces a regression is thus reduced to a binary search: repeatedly
|
||||
generate and test new 'midpoint's until the commit chain is of length
|
||||
one.
|
||||
|
||||
--bisect-vars::
|
||||
|
||||
This calculates the same as `--bisect`, but outputs text ready
|
||||
to be eval'ed by the shell. These lines will assign the name of
|
||||
the midpoint revision to the variable `bisect_rev`, and the
|
||||
expected number of commits to be tested after `bisect_rev` is
|
||||
tested to `bisect_nr`, the expected number of commits to be
|
||||
tested if `bisect_rev` turns out to be good to `bisect_good`,
|
||||
the expected number of commits to be tested if `bisect_rev`
|
||||
turns out to be bad to `bisect_bad`, and the number of commits
|
||||
we are bisecting right now to `bisect_all`.
|
||||
|
||||
--
|
||||
|
||||
Commit Ordering
|
||||
|
||||
84
Makefile
84
Makefile
@@ -110,6 +110,14 @@ all:
|
||||
# Define NO_PERL_MAKEMAKER if you cannot use Makefiles generated by perl's
|
||||
# MakeMaker (e.g. using ActiveState under Cygwin).
|
||||
#
|
||||
# Define WITH_P4IMPORT to build and install Python git-p4import script.
|
||||
#
|
||||
# Define NO_TCLTK if you do not want Tcl/Tk GUI.
|
||||
#
|
||||
# The TCLTK_PATH variable governs the location of the Tck/Tk interpreter.
|
||||
# If not set it defaults to the bare 'wish'. If it is set to the empty
|
||||
# string then NO_TCLTK will be forced (this is used by configure script).
|
||||
#
|
||||
|
||||
GIT-VERSION-FILE: .FORCE-GIT-VERSION-FILE
|
||||
@$(SHELL_PATH) ./GIT-VERSION-GEN
|
||||
@@ -159,6 +167,7 @@ AR = ar
|
||||
TAR = tar
|
||||
INSTALL = install
|
||||
RPMBUILD = rpmbuild
|
||||
TCLTK_PATH = wish
|
||||
|
||||
# sparse is architecture-neutral, which means that we need to tell it
|
||||
# explicitly what architecture to check for. Fix this up for yours..
|
||||
@@ -197,9 +206,20 @@ SCRIPT_PERL = \
|
||||
git-svnimport.perl git-cvsexportcommit.perl \
|
||||
git-send-email.perl git-svn.perl
|
||||
|
||||
SCRIPT_PYTHON = \
|
||||
git-p4import.py
|
||||
|
||||
ifdef WITH_P4IMPORT
|
||||
SCRIPTS = $(patsubst %.sh,%,$(SCRIPT_SH)) \
|
||||
$(patsubst %.perl,%,$(SCRIPT_PERL)) \
|
||||
$(patsubst %.py,%,$(SCRIPT_PYTHON)) \
|
||||
git-status git-instaweb
|
||||
else
|
||||
SCRIPTS = $(patsubst %.sh,%,$(SCRIPT_SH)) \
|
||||
$(patsubst %.perl,%,$(SCRIPT_PERL)) \
|
||||
git-status git-instaweb
|
||||
endif
|
||||
|
||||
|
||||
# ... and all the rest that could be moved out of bindir to gitexecdir
|
||||
PROGRAMS = \
|
||||
@@ -230,6 +250,12 @@ BUILT_INS = \
|
||||
# what 'all' will build and 'install' will install, in gitexecdir
|
||||
ALL_PROGRAMS = $(PROGRAMS) $(SCRIPTS)
|
||||
|
||||
# what 'all' will build but not install in gitexecdir
|
||||
OTHER_PROGRAMS = git$X gitweb/gitweb.cgi
|
||||
ifndef NO_TCLTK
|
||||
OTHER_PROGRAMS += gitk-wish
|
||||
endif
|
||||
|
||||
# Backward compatibility -- to be removed after 1.0
|
||||
PROGRAMS += git-ssh-pull$X git-ssh-push$X
|
||||
|
||||
@@ -240,6 +266,9 @@ endif
|
||||
ifndef PERL_PATH
|
||||
PERL_PATH = /usr/bin/perl
|
||||
endif
|
||||
ifndef PYTHON_PATH
|
||||
PYTHON_PATH = /usr/local/bin/python
|
||||
endif
|
||||
|
||||
export PERL_PATH
|
||||
|
||||
@@ -635,6 +664,10 @@ ifdef NO_PERL_MAKEMAKER
|
||||
export NO_PERL_MAKEMAKER
|
||||
endif
|
||||
|
||||
ifeq ($(TCLTK_PATH),)
|
||||
NO_TCLTK=NoThanks
|
||||
endif
|
||||
|
||||
QUIET_SUBDIR0 = $(MAKE) -C # space to separate -C and subdir
|
||||
QUIET_SUBDIR1 =
|
||||
|
||||
@@ -673,6 +706,8 @@ prefix_SQ = $(subst ','\'',$(prefix))
|
||||
|
||||
SHELL_PATH_SQ = $(subst ','\'',$(SHELL_PATH))
|
||||
PERL_PATH_SQ = $(subst ','\'',$(PERL_PATH))
|
||||
PYTHON_PATH_SQ = $(subst ','\'',$(PYTHON_PATH))
|
||||
TCLTK_PATH_SQ = $(subst ','\'',$(TCLTK_PATH))
|
||||
|
||||
LIBS = $(GITLIBS) $(EXTLIBS)
|
||||
|
||||
@@ -688,16 +723,24 @@ export prefix gitexecdir TAR INSTALL DESTDIR SHELL_PATH template_dir
|
||||
|
||||
### Build rules
|
||||
|
||||
all: $(ALL_PROGRAMS) $(BUILT_INS) git$X gitk gitweb/gitweb.cgi
|
||||
all: $(ALL_PROGRAMS) $(BUILT_INS) $(OTHER_PROGRAMS)
|
||||
|
||||
all:
|
||||
$(QUIET_SUBDIR0)git-gui $(QUIET_SUBDIR1) all
|
||||
ifndef NO_TCLTK
|
||||
$(QUIET_SUBDIR0)git-gui $(QUIET_SUBDIR1) TCLTK_PATH='$(TCLTK_PATH_SQ)' all
|
||||
endif
|
||||
$(QUIET_SUBDIR0)perl $(QUIET_SUBDIR1) PERL_PATH='$(PERL_PATH_SQ)' prefix='$(prefix_SQ)' all
|
||||
$(QUIET_SUBDIR0)templates $(QUIET_SUBDIR1) NOEXECTEMPL='$(NOEXECTEMPL)'
|
||||
|
||||
strip: $(PROGRAMS) git$X
|
||||
$(STRIP) $(STRIP_OPTS) $(PROGRAMS) git$X
|
||||
|
||||
gitk-wish: gitk GIT-GUI-VARS
|
||||
$(QUIET_GEN)rm -f $@ $@+ && \
|
||||
sed -e '1,3s|^exec .* "$$0"|exec $(subst |,'\|',$(TCLTK_PATH_SQ)) "$$0"|' <gitk >$@+ && \
|
||||
chmod +x $@+ && \
|
||||
mv -f $@+ $@
|
||||
|
||||
git$X: git.c common-cmds.h $(BUILTIN_OBJS) $(GITLIBS) GIT-CFLAGS
|
||||
$(QUIET_LINK)$(CC) -DGIT_VERSION='"$(GIT_VERSION)"' \
|
||||
$(ALL_CFLAGS) -o $@ $(filter %.c,$^) \
|
||||
@@ -708,7 +751,7 @@ help.o: common-cmds.h
|
||||
$(BUILT_INS): git$X
|
||||
$(QUIET_BUILT_IN)rm -f $@ && ln git$X $@
|
||||
|
||||
common-cmds.h: Documentation/git-*.txt
|
||||
common-cmds.h: $(wildcard Documentation/git-*.txt)
|
||||
$(QUIET_GEN)./generate-cmdlist.sh > $@+ && mv $@+ $@
|
||||
|
||||
$(patsubst %.sh,%,$(SCRIPT_SH)) : % : %.sh
|
||||
@@ -723,6 +766,15 @@ $(patsubst %.sh,%,$(SCRIPT_SH)) : % : %.sh
|
||||
|
||||
$(patsubst %.perl,%,$(SCRIPT_PERL)): perl/perl.mak
|
||||
|
||||
$(patsubst %.py,%,$(SCRIPT_PYTHON)) : % : %.py
|
||||
rm -f $@ $@+
|
||||
sed -e '1s|#!.*/python|#!$(PYTHON_PATH_SQ)|' \
|
||||
-e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \
|
||||
-e 's/@@NO_CURL@@/$(NO_CURL)/g' \
|
||||
$@.py >$@+
|
||||
chmod +x $@+
|
||||
mv $@+ $@
|
||||
|
||||
perl/perl.mak: GIT-CFLAGS
|
||||
$(QUIET_SUBDIR0)perl $(QUIET_SUBDIR1) PERL_PATH='$(PERL_PATH_SQ)' prefix='$(prefix_SQ)' $(@F)
|
||||
|
||||
@@ -876,6 +928,20 @@ GIT-CFLAGS: .FORCE-GIT-CFLAGS
|
||||
echo "$$FLAGS" >GIT-CFLAGS; \
|
||||
fi
|
||||
|
||||
### Detect Tck/Tk interpreter path changes
|
||||
ifndef NO_TCLTK
|
||||
TRACK_VARS = $(subst ','\'',-DTCLTK_PATH='$(TCLTK_PATH_SQ)')
|
||||
|
||||
GIT-GUI-VARS: .FORCE-GIT-GUI-VARS
|
||||
@VARS='$(TRACK_VARS)'; \
|
||||
if test x"$$VARS" != x"`cat $@ 2>/dev/null`" ; then \
|
||||
echo 1>&2 " * new Tcl/Tk interpreter location"; \
|
||||
echo "$$VARS" >$@; \
|
||||
fi
|
||||
|
||||
.PHONY: .FORCE-GIT-GUI-VARS
|
||||
endif
|
||||
|
||||
### Testing rules
|
||||
|
||||
# GNU make supports exporting all variables by "export" without parameters.
|
||||
@@ -917,10 +983,13 @@ install: all
|
||||
$(INSTALL) -d -m755 '$(DESTDIR_SQ)$(bindir_SQ)'
|
||||
$(INSTALL) -d -m755 '$(DESTDIR_SQ)$(gitexecdir_SQ)'
|
||||
$(INSTALL) $(ALL_PROGRAMS) '$(DESTDIR_SQ)$(gitexecdir_SQ)'
|
||||
$(INSTALL) git$X gitk '$(DESTDIR_SQ)$(bindir_SQ)'
|
||||
$(INSTALL) git$X '$(DESTDIR_SQ)$(bindir_SQ)'
|
||||
$(MAKE) -C templates DESTDIR='$(DESTDIR_SQ)' install
|
||||
$(MAKE) -C perl prefix='$(prefix_SQ)' install
|
||||
ifndef NO_TCLTK
|
||||
$(INSTALL) gitk-wish '$(DESTDIR_SQ)$(bindir_SQ)'/gitk
|
||||
$(MAKE) -C git-gui install
|
||||
endif
|
||||
if test 'z$(bindir_SQ)' != 'z$(gitexecdir_SQ)'; \
|
||||
then \
|
||||
ln -f '$(DESTDIR_SQ)$(bindir_SQ)/git$X' \
|
||||
@@ -996,10 +1065,13 @@ clean:
|
||||
rm -f gitweb/gitweb.cgi
|
||||
$(MAKE) -C Documentation/ clean
|
||||
$(MAKE) -C perl clean
|
||||
$(MAKE) -C git-gui clean
|
||||
$(MAKE) -C templates/ clean
|
||||
$(MAKE) -C t/ clean
|
||||
rm -f GIT-VERSION-FILE GIT-CFLAGS
|
||||
ifndef NO_TCLTK
|
||||
rm -f gitk-wish
|
||||
$(MAKE) -C git-gui clean
|
||||
endif
|
||||
rm -f GIT-VERSION-FILE GIT-CFLAGS GIT-GUI-VARS
|
||||
|
||||
.PHONY: all install clean strip
|
||||
.PHONY: .FORCE-GIT-VERSION-FILE TAGS tags .FORCE-GIT-CFLAGS
|
||||
|
||||
@@ -87,7 +87,7 @@ static void fill_directory(struct dir_struct *dir, const char **pathspec)
|
||||
}
|
||||
|
||||
/* Read the directory and prune it */
|
||||
read_directory(dir, path, base, baselen);
|
||||
read_directory(dir, path, base, baselen, pathspec);
|
||||
if (pathspec)
|
||||
prune_directory(dir, pathspec, baselen);
|
||||
}
|
||||
@@ -205,7 +205,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)
|
||||
}
|
||||
|
||||
for (i = 0; i < dir.nr; i++)
|
||||
add_file_to_index(dir.entries[i]->name, verbose);
|
||||
add_file_to_cache(dir.entries[i]->name, verbose);
|
||||
|
||||
if (active_cache_changed) {
|
||||
if (write_cache(newfd, active_cache, active_nr) ||
|
||||
|
||||
@@ -30,7 +30,7 @@ static int unidiff_zero;
|
||||
static int p_value = 1;
|
||||
static int p_value_known;
|
||||
static int check_index;
|
||||
static int write_index;
|
||||
static int update_index;
|
||||
static int cached;
|
||||
static int diffstat;
|
||||
static int numstat;
|
||||
@@ -417,7 +417,7 @@ static int gitdiff_hdrend(const char *line, struct patch *patch)
|
||||
static char *gitdiff_verify_name(const char *line, int isnull, char *orig_name, const char *oldnew)
|
||||
{
|
||||
if (!orig_name && !isnull)
|
||||
return find_name(line, NULL, 1, TERM_TAB);
|
||||
return find_name(line, NULL, p_value, TERM_TAB);
|
||||
|
||||
if (orig_name) {
|
||||
int len;
|
||||
@@ -427,7 +427,7 @@ static char *gitdiff_verify_name(const char *line, int isnull, char *orig_name,
|
||||
len = strlen(name);
|
||||
if (isnull)
|
||||
die("git-apply: bad git-diff - expected /dev/null, got %s on line %d", name, linenr);
|
||||
another = find_name(line, NULL, 1, TERM_TAB);
|
||||
another = find_name(line, NULL, p_value, TERM_TAB);
|
||||
if (!another || memcmp(another, name, len))
|
||||
die("git-apply: bad git-diff - inconsistent %s filename on line %d", oldnew, linenr);
|
||||
free(another);
|
||||
@@ -2308,7 +2308,7 @@ static void patch_stats(struct patch *patch)
|
||||
|
||||
static void remove_file(struct patch *patch, int rmdir_empty)
|
||||
{
|
||||
if (write_index) {
|
||||
if (update_index) {
|
||||
if (remove_file_from_cache(patch->old_name) < 0)
|
||||
die("unable to remove %s from index", patch->old_name);
|
||||
cache_tree_invalidate_path(active_cache_tree, patch->old_name);
|
||||
@@ -2335,7 +2335,7 @@ static void add_index_file(const char *path, unsigned mode, void *buf, unsigned
|
||||
int namelen = strlen(path);
|
||||
unsigned ce_size = cache_entry_size(namelen);
|
||||
|
||||
if (!write_index)
|
||||
if (!update_index)
|
||||
return;
|
||||
|
||||
ce = xcalloc(1, ce_size);
|
||||
@@ -2662,8 +2662,8 @@ static int apply_patch(int fd, const char *filename, int inaccurate_eof)
|
||||
if (whitespace_error && (new_whitespace == error_on_whitespace))
|
||||
apply = 0;
|
||||
|
||||
write_index = check_index && apply;
|
||||
if (write_index && newfd < 0)
|
||||
update_index = check_index && apply;
|
||||
if (update_index && newfd < 0)
|
||||
newfd = hold_lock_file_for_update(&lock_file,
|
||||
get_index_file(), 1);
|
||||
if (check_index) {
|
||||
@@ -2870,7 +2870,7 @@ int cmd_apply(int argc, const char **argv, const char *unused_prefix)
|
||||
whitespace_error == 1 ? "s" : "");
|
||||
}
|
||||
|
||||
if (write_index) {
|
||||
if (update_index) {
|
||||
if (write_cache(newfd, active_cache, active_nr) ||
|
||||
close(newfd) || commit_lock_file(&lock_file))
|
||||
die("Unable to write new index file");
|
||||
|
||||
@@ -252,6 +252,8 @@ int cmd_archive(int argc, const char **argv, const char *prefix)
|
||||
|
||||
memset(&ar, 0, sizeof(ar));
|
||||
tree_idx = parse_archive_args(argc, argv, &ar);
|
||||
if (prefix == NULL)
|
||||
prefix = setup_git_directory();
|
||||
|
||||
argv += tree_idx;
|
||||
parse_treeish_arg(argv, &ar.args, prefix);
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
static int show_root;
|
||||
static int show_tags;
|
||||
static int show_unreachable;
|
||||
static int include_reflogs = 1;
|
||||
static int check_full;
|
||||
static int check_strict;
|
||||
static int keep_cache_objects;
|
||||
@@ -348,7 +349,7 @@ static int fsck_tag(struct tag *tag)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fsck_sha1(unsigned char *sha1)
|
||||
static int fsck_sha1(const unsigned char *sha1)
|
||||
{
|
||||
struct object *obj = parse_object(sha1);
|
||||
if (!obj) {
|
||||
@@ -517,7 +518,8 @@ static int fsck_handle_ref(const char *refname, const unsigned char *sha1, int f
|
||||
static void get_default_heads(void)
|
||||
{
|
||||
for_each_ref(fsck_handle_ref, NULL);
|
||||
for_each_reflog(fsck_handle_reflog, NULL);
|
||||
if (include_reflogs)
|
||||
for_each_reflog(fsck_handle_reflog, NULL);
|
||||
|
||||
/*
|
||||
* Not having any default heads isn't really fatal, but
|
||||
@@ -616,6 +618,10 @@ int cmd_fsck(int argc, char **argv, const char *prefix)
|
||||
keep_cache_objects = 1;
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(arg, "--no-reflogs")) {
|
||||
include_reflogs = 0;
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(arg, "--full")) {
|
||||
check_full = 1;
|
||||
continue;
|
||||
@@ -648,11 +654,8 @@ int cmd_fsck(int argc, char **argv, const char *prefix)
|
||||
|
||||
for (p = packed_git; p; p = p->next) {
|
||||
uint32_t i, num = num_packed_objects(p);
|
||||
for (i = 0; i < num; i++) {
|
||||
unsigned char sha1[20];
|
||||
nth_packed_object_sha1(p, i, sha1);
|
||||
fsck_sha1(sha1);
|
||||
}
|
||||
for (i = 0; i < num; i++)
|
||||
fsck_sha1(nth_packed_object_sha1(p, i));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -216,7 +216,7 @@ static void show_files(struct dir_struct *dir, const char *prefix)
|
||||
|
||||
if (baselen)
|
||||
path = base = prefix;
|
||||
read_directory(dir, path, base, baselen);
|
||||
read_directory(dir, path, base, baselen, pathspec);
|
||||
if (show_others)
|
||||
show_other_files(dir);
|
||||
if (show_killed)
|
||||
|
||||
@@ -273,7 +273,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
|
||||
|
||||
for (i = 0; i < added.nr; i++) {
|
||||
const char *path = added.items[i].path;
|
||||
add_file_to_index(path, verbose);
|
||||
add_file_to_cache(path, verbose);
|
||||
}
|
||||
|
||||
for (i = 0; i < deleted.nr; i++) {
|
||||
|
||||
@@ -222,7 +222,7 @@ static const unsigned char *find_packed_object_name(struct packed_git *p,
|
||||
off_t ofs)
|
||||
{
|
||||
struct revindex_entry *entry = find_packed_object(p, ofs);
|
||||
return ((unsigned char *)p->index_data) + 4 * 256 + 24 * entry->nr + 4;
|
||||
return nth_packed_object_sha1(p, entry->nr);
|
||||
}
|
||||
|
||||
static void *delta_against(void *buf, unsigned long size, struct object_entry *entry)
|
||||
|
||||
@@ -117,10 +117,13 @@ static int handle_file(const char *path,
|
||||
else if (!prefixcmp(buf, "======="))
|
||||
hunk = 2;
|
||||
else if (!prefixcmp(buf, ">>>>>>> ")) {
|
||||
int one_is_longer = (one->nr > two->nr);
|
||||
int common_len = one_is_longer ? two->nr : one->nr;
|
||||
int cmp = memcmp(one->ptr, two->ptr, common_len);
|
||||
|
||||
hunk_no++;
|
||||
hunk = 0;
|
||||
if (memcmp(one->ptr, two->ptr, one->nr < two->nr ?
|
||||
one->nr : two->nr) > 0) {
|
||||
if ((cmp > 0) || ((cmp == 0) && one_is_longer)) {
|
||||
struct buffer *swap = one;
|
||||
one = two;
|
||||
two = swap;
|
||||
|
||||
@@ -35,8 +35,10 @@ static const char rev_list_usage[] =
|
||||
" --header | --pretty\n"
|
||||
" --abbrev=nr | --no-abbrev\n"
|
||||
" --abbrev-commit\n"
|
||||
" --left-right\n"
|
||||
" special purpose:\n"
|
||||
" --bisect"
|
||||
" --bisect\n"
|
||||
" --bisect-vars"
|
||||
;
|
||||
|
||||
static struct rev_info revs;
|
||||
@@ -168,38 +170,273 @@ static void clear_distance(struct commit_list *list)
|
||||
}
|
||||
}
|
||||
|
||||
static struct commit_list *find_bisection(struct commit_list *list)
|
||||
{
|
||||
int nr, closest;
|
||||
struct commit_list *p, *best;
|
||||
#define DEBUG_BISECT 0
|
||||
|
||||
nr = 0;
|
||||
p = list;
|
||||
while (p) {
|
||||
if (!revs.prune_fn || (p->item->object.flags & TREECHANGE))
|
||||
nr++;
|
||||
p = p->next;
|
||||
static inline int weight(struct commit_list *elem)
|
||||
{
|
||||
return *((int*)(elem->item->util));
|
||||
}
|
||||
|
||||
static inline void weight_set(struct commit_list *elem, int weight)
|
||||
{
|
||||
*((int*)(elem->item->util)) = weight;
|
||||
}
|
||||
|
||||
static int count_interesting_parents(struct commit *commit)
|
||||
{
|
||||
struct commit_list *p;
|
||||
int count;
|
||||
|
||||
for (count = 0, p = commit->parents; p; p = p->next) {
|
||||
if (p->item->object.flags & UNINTERESTING)
|
||||
continue;
|
||||
count++;
|
||||
}
|
||||
closest = -1;
|
||||
best = list;
|
||||
return count;
|
||||
}
|
||||
|
||||
static inline int halfway(struct commit_list *p, int distance, int nr)
|
||||
{
|
||||
/*
|
||||
* Don't short-cut something we are not going to return!
|
||||
*/
|
||||
if (revs.prune_fn && !(p->item->object.flags & TREECHANGE))
|
||||
return 0;
|
||||
if (DEBUG_BISECT)
|
||||
return 0;
|
||||
/*
|
||||
* 2 and 3 are halfway of 5.
|
||||
* 3 is halfway of 6 but 2 and 4 are not.
|
||||
*/
|
||||
distance *= 2;
|
||||
switch (distance - nr) {
|
||||
case -1: case 0: case 1:
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#if !DEBUG_BISECT
|
||||
#define show_list(a,b,c,d) do { ; } while (0)
|
||||
#else
|
||||
static void show_list(const char *debug, int counted, int nr,
|
||||
struct commit_list *list)
|
||||
{
|
||||
struct commit_list *p;
|
||||
|
||||
fprintf(stderr, "%s (%d/%d)\n", debug, counted, nr);
|
||||
|
||||
for (p = list; p; p = p->next) {
|
||||
int distance;
|
||||
struct commit_list *pp;
|
||||
struct commit *commit = p->item;
|
||||
unsigned flags = commit->object.flags;
|
||||
enum object_type type;
|
||||
unsigned long size;
|
||||
char *buf = read_sha1_file(commit->object.sha1, &type, &size);
|
||||
char *ep, *sp;
|
||||
|
||||
if (revs.prune_fn && !(p->item->object.flags & TREECHANGE))
|
||||
fprintf(stderr, "%c%c%c ",
|
||||
(flags & TREECHANGE) ? 'T' : ' ',
|
||||
(flags & UNINTERESTING) ? 'U' : ' ',
|
||||
(flags & COUNTED) ? 'C' : ' ');
|
||||
if (commit->util)
|
||||
fprintf(stderr, "%3d", weight(p));
|
||||
else
|
||||
fprintf(stderr, "---");
|
||||
fprintf(stderr, " %.*s", 8, sha1_to_hex(commit->object.sha1));
|
||||
for (pp = commit->parents; pp; pp = pp->next)
|
||||
fprintf(stderr, " %.*s", 8,
|
||||
sha1_to_hex(pp->item->object.sha1));
|
||||
|
||||
sp = strstr(buf, "\n\n");
|
||||
if (sp) {
|
||||
sp += 2;
|
||||
for (ep = sp; *ep && *ep != '\n'; ep++)
|
||||
;
|
||||
fprintf(stderr, " %.*s", (int)(ep - sp), sp);
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
}
|
||||
#endif /* DEBUG_BISECT */
|
||||
|
||||
/*
|
||||
* zero or positive weight is the number of interesting commits it can
|
||||
* reach, including itself. Especially, weight = 0 means it does not
|
||||
* reach any tree-changing commits (e.g. just above uninteresting one
|
||||
* but traversal is with pathspec).
|
||||
*
|
||||
* weight = -1 means it has one parent and its distance is yet to
|
||||
* be computed.
|
||||
*
|
||||
* weight = -2 means it has more than one parent and its distance is
|
||||
* unknown. After running count_distance() first, they will get zero
|
||||
* or positive distance.
|
||||
*/
|
||||
|
||||
static struct commit_list *find_bisection(struct commit_list *list,
|
||||
int *reaches, int *all)
|
||||
{
|
||||
int n, nr, on_list, counted, distance;
|
||||
struct commit_list *p, *best, *next, *last;
|
||||
int *weights;
|
||||
|
||||
show_list("bisection 2 entry", 0, 0, list);
|
||||
|
||||
/*
|
||||
* Count the number of total and tree-changing items on the
|
||||
* list, while reversing the list.
|
||||
*/
|
||||
for (nr = on_list = 0, last = NULL, p = list;
|
||||
p;
|
||||
p = next) {
|
||||
unsigned flags = p->item->object.flags;
|
||||
|
||||
next = p->next;
|
||||
if (flags & UNINTERESTING)
|
||||
continue;
|
||||
p->next = last;
|
||||
last = p;
|
||||
if (!revs.prune_fn || (flags & TREECHANGE))
|
||||
nr++;
|
||||
on_list++;
|
||||
}
|
||||
list = last;
|
||||
show_list("bisection 2 sorted", 0, nr, list);
|
||||
|
||||
*all = nr;
|
||||
weights = xcalloc(on_list, sizeof(int*));
|
||||
counted = 0;
|
||||
|
||||
for (n = 0, p = list; p; p = p->next) {
|
||||
struct commit *commit = p->item;
|
||||
unsigned flags = commit->object.flags;
|
||||
|
||||
p->item->util = &weights[n++];
|
||||
switch (count_interesting_parents(commit)) {
|
||||
case 0:
|
||||
if (!revs.prune_fn || (flags & TREECHANGE)) {
|
||||
weight_set(p, 1);
|
||||
counted++;
|
||||
show_list("bisection 2 count one",
|
||||
counted, nr, list);
|
||||
}
|
||||
/*
|
||||
* otherwise, it is known not to reach any
|
||||
* tree-changing commit and gets weight 0.
|
||||
*/
|
||||
break;
|
||||
case 1:
|
||||
weight_set(p, -1);
|
||||
break;
|
||||
default:
|
||||
weight_set(p, -2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
show_list("bisection 2 initialize", counted, nr, list);
|
||||
|
||||
/*
|
||||
* If you have only one parent in the resulting set
|
||||
* then you can reach one commit more than that parent
|
||||
* can reach. So we do not have to run the expensive
|
||||
* count_distance() for single strand of pearls.
|
||||
*
|
||||
* However, if you have more than one parents, you cannot
|
||||
* just add their distance and one for yourself, since
|
||||
* they usually reach the same ancestor and you would
|
||||
* end up counting them twice that way.
|
||||
*
|
||||
* So we will first count distance of merges the usual
|
||||
* way, and then fill the blanks using cheaper algorithm.
|
||||
*/
|
||||
for (p = list; p; p = p->next) {
|
||||
if (p->item->object.flags & UNINTERESTING)
|
||||
continue;
|
||||
n = weight(p);
|
||||
if (n != -2)
|
||||
continue;
|
||||
distance = count_distance(p);
|
||||
clear_distance(list);
|
||||
weight_set(p, distance);
|
||||
|
||||
/* Does it happen to be at exactly half-way? */
|
||||
if (halfway(p, distance, nr)) {
|
||||
p->next = NULL;
|
||||
*reaches = distance;
|
||||
free(weights);
|
||||
return p;
|
||||
}
|
||||
counted++;
|
||||
}
|
||||
|
||||
show_list("bisection 2 count_distance", counted, nr, list);
|
||||
|
||||
while (counted < nr) {
|
||||
for (p = list; p; p = p->next) {
|
||||
struct commit_list *q;
|
||||
unsigned flags = p->item->object.flags;
|
||||
|
||||
if (0 <= weight(p))
|
||||
continue;
|
||||
for (q = p->item->parents; q; q = q->next) {
|
||||
if (q->item->object.flags & UNINTERESTING)
|
||||
continue;
|
||||
if (0 <= weight(q))
|
||||
break;
|
||||
}
|
||||
if (!q)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* weight for p is unknown but q is known.
|
||||
* add one for p itself if p is to be counted,
|
||||
* otherwise inherit it from q directly.
|
||||
*/
|
||||
if (!revs.prune_fn || (flags & TREECHANGE)) {
|
||||
weight_set(p, weight(q)+1);
|
||||
counted++;
|
||||
show_list("bisection 2 count one",
|
||||
counted, nr, list);
|
||||
}
|
||||
else
|
||||
weight_set(p, weight(q));
|
||||
|
||||
/* Does it happen to be at exactly half-way? */
|
||||
distance = weight(p);
|
||||
if (halfway(p, distance, nr)) {
|
||||
p->next = NULL;
|
||||
*reaches = distance;
|
||||
free(weights);
|
||||
return p;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
show_list("bisection 2 counted all", counted, nr, list);
|
||||
|
||||
/* Then find the best one */
|
||||
counted = -1;
|
||||
best = list;
|
||||
for (p = list; p; p = p->next) {
|
||||
unsigned flags = p->item->object.flags;
|
||||
|
||||
if (revs.prune_fn && !(flags & TREECHANGE))
|
||||
continue;
|
||||
distance = weight(p);
|
||||
if (nr - distance < distance)
|
||||
distance = nr - distance;
|
||||
if (distance > closest) {
|
||||
if (distance > counted) {
|
||||
best = p;
|
||||
closest = distance;
|
||||
counted = distance;
|
||||
*reaches = weight(p);
|
||||
}
|
||||
}
|
||||
if (best)
|
||||
best->next = NULL;
|
||||
free(weights);
|
||||
return best;
|
||||
}
|
||||
|
||||
@@ -225,6 +462,7 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
|
||||
struct commit_list *list;
|
||||
int i;
|
||||
int read_from_stdin = 0;
|
||||
int bisect_show_vars = 0;
|
||||
|
||||
git_config(git_default_config);
|
||||
init_revisions(&revs, prefix);
|
||||
@@ -247,6 +485,11 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
|
||||
bisect_list = 1;
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(arg, "--bisect-vars")) {
|
||||
bisect_list = 1;
|
||||
bisect_show_vars = 1;
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(arg, "--stdin")) {
|
||||
if (read_from_stdin++)
|
||||
die("--stdin given twice?");
|
||||
@@ -285,8 +528,39 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
|
||||
if (revs.tree_objects)
|
||||
mark_edges_uninteresting(revs.commits, &revs, show_edge);
|
||||
|
||||
if (bisect_list)
|
||||
revs.commits = find_bisection(revs.commits);
|
||||
if (bisect_list) {
|
||||
int reaches = reaches, all = all;
|
||||
|
||||
revs.commits = find_bisection(revs.commits, &reaches, &all);
|
||||
if (bisect_show_vars) {
|
||||
int cnt;
|
||||
if (!revs.commits)
|
||||
return 1;
|
||||
/*
|
||||
* revs.commits can reach "reaches" commits among
|
||||
* "all" commits. If it is good, then there are
|
||||
* (all-reaches) commits left to be bisected.
|
||||
* On the other hand, if it is bad, then the set
|
||||
* to bisect is "reaches".
|
||||
* A bisect set of size N has (N-1) commits further
|
||||
* to test, as we already know one bad one.
|
||||
*/
|
||||
cnt = all-reaches;
|
||||
if (cnt < reaches)
|
||||
cnt = reaches;
|
||||
printf("bisect_rev=%s\n"
|
||||
"bisect_nr=%d\n"
|
||||
"bisect_good=%d\n"
|
||||
"bisect_bad=%d\n"
|
||||
"bisect_all=%d\n",
|
||||
sha1_to_hex(revs.commits->item->object.sha1),
|
||||
cnt - 1,
|
||||
all - reaches - 1,
|
||||
reaches - 1,
|
||||
all);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
traverse_commit_list(&revs, show_commit, show_object);
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ static int mark_valid(const char *path)
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int add_file_to_cache(const char *path)
|
||||
static int process_file(const char *path)
|
||||
{
|
||||
int size, namelen, option, status;
|
||||
struct cache_entry *ce;
|
||||
@@ -210,7 +210,7 @@ static void update_one(const char *path, const char *prefix, int prefix_length)
|
||||
report("remove '%s'", path);
|
||||
goto free_return;
|
||||
}
|
||||
if (add_file_to_cache(p))
|
||||
if (process_file(p))
|
||||
die("Unable to process file %s", path);
|
||||
report("add '%s'", path);
|
||||
free_return:
|
||||
|
||||
5
cache.h
5
cache.h
@@ -128,7 +128,6 @@ static inline unsigned int ce_mode_from_stat(struct cache_entry *ce, unsigned in
|
||||
extern struct cache_entry **active_cache;
|
||||
extern unsigned int active_nr, active_alloc, active_cache_changed;
|
||||
extern struct cache_tree *active_cache_tree;
|
||||
extern int cache_errno;
|
||||
|
||||
enum object_type {
|
||||
OBJ_BAD = -1,
|
||||
@@ -188,7 +187,7 @@ extern int add_cache_entry(struct cache_entry *ce, int option);
|
||||
extern struct cache_entry *refresh_cache_entry(struct cache_entry *ce, int really);
|
||||
extern int remove_cache_entry_at(int pos);
|
||||
extern int remove_file_from_cache(const char *path);
|
||||
extern int add_file_to_index(const char *path, int verbose);
|
||||
extern int add_file_to_cache(const char *path, int verbose);
|
||||
extern int ce_same_name(struct cache_entry *a, struct cache_entry *b);
|
||||
extern int ce_match_stat(struct cache_entry *ce, struct stat *st, int);
|
||||
extern int ce_modified(struct cache_entry *ce, struct stat *st, int);
|
||||
@@ -429,7 +428,7 @@ extern unsigned char* use_pack(struct packed_git *, struct pack_window **, off_t
|
||||
extern void unuse_pack(struct pack_window **);
|
||||
extern struct packed_git *add_packed_git(const char *, int, int);
|
||||
extern uint32_t num_packed_objects(const struct packed_git *p);
|
||||
extern int nth_packed_object_sha1(const struct packed_git *, uint32_t, unsigned char*);
|
||||
extern const unsigned char *nth_packed_object_sha1(const struct packed_git *, uint32_t);
|
||||
extern off_t find_pack_entry_one(const unsigned char *, struct packed_git *);
|
||||
extern void *unpack_entry(struct packed_git *, off_t, enum object_type *, unsigned long *);
|
||||
extern unsigned long unpack_object_header_gently(const unsigned char *buf, unsigned long len, enum object_type *type, unsigned long *sizep);
|
||||
|
||||
5
config.c
5
config.c
@@ -918,8 +918,8 @@ int git_config_rename_section(const char *old_name, const char *new_name)
|
||||
}
|
||||
|
||||
if (!(config_file = fopen(config_filename, "rb"))) {
|
||||
ret = error("Could not open config file!");
|
||||
goto out;
|
||||
/* no config file means nothing to rename, no error */
|
||||
goto unlock_and_out;
|
||||
}
|
||||
|
||||
while (fgets(buf, sizeof(buf), config_file)) {
|
||||
@@ -953,6 +953,7 @@ int git_config_rename_section(const char *old_name, const char *new_name)
|
||||
}
|
||||
}
|
||||
fclose(config_file);
|
||||
unlock_and_out:
|
||||
if (close(out_fd) || commit_lock_file(lock) < 0)
|
||||
ret = error("Cannot commit config file!");
|
||||
out:
|
||||
|
||||
@@ -6,6 +6,7 @@ CFLAGS = @CFLAGS@
|
||||
AR = @AR@
|
||||
TAR = @TAR@
|
||||
#INSTALL = @INSTALL@ # needs install-sh or install.sh in sources
|
||||
TCLTK_PATH = @TCLTK_PATH@
|
||||
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
|
||||
24
configure.ac
24
configure.ac
@@ -75,6 +75,14 @@ GIT_ARG_SET_PATH(shell)
|
||||
# Define PERL_PATH to provide path to Perl.
|
||||
GIT_ARG_SET_PATH(perl)
|
||||
#
|
||||
# Declare the with-tcltk/without-tcltk options.
|
||||
AC_ARG_WITH(tcltk,
|
||||
AS_HELP_STRING([--with-tcltk],[use Tcl/Tk GUI (default is YES)])
|
||||
AS_HELP_STRING([],[ARG is the full path to the Tcl/Tk interpreter.])
|
||||
AS_HELP_STRING([],[Bare --with-tcltk will make the GUI part only if])
|
||||
AS_HELP_STRING([],[Tcl/Tk interpreter will be found in a system.]),\
|
||||
GIT_PARSE_WITH(tcltk))
|
||||
#
|
||||
|
||||
|
||||
## Checks for programs.
|
||||
@@ -84,6 +92,22 @@ AC_PROG_CC([cc gcc])
|
||||
#AC_PROG_INSTALL # needs install-sh or install.sh in sources
|
||||
AC_CHECK_TOOL(AR, ar, :)
|
||||
AC_CHECK_PROGS(TAR, [gtar tar])
|
||||
# TCLTK_PATH will be set to some value if we want Tcl/Tk
|
||||
# or will be empty otherwise.
|
||||
if test -z "$NO_TCLTK"; then
|
||||
if test "$with_tcltk" = ""; then
|
||||
# No Tcl/Tk switches given. Do not check for Tcl/Tk, use bare 'wish'.
|
||||
TCLTK_PATH=wish
|
||||
AC_SUBST(TCLTK_PATH)
|
||||
elif test "$with_tcltk" = "yes"; then
|
||||
# Tcl/Tk check requested.
|
||||
AC_CHECK_PROGS(TCLTK_PATH, [wish], )
|
||||
else
|
||||
AC_MSG_RESULT([Using Tcl/Tk interpreter $with_tcltk])
|
||||
TCLTK_PATH="$with_tcltk"
|
||||
AC_SUBST(TCLTK_PATH)
|
||||
fi
|
||||
fi
|
||||
|
||||
## Checks for libraries.
|
||||
AC_MSG_NOTICE([CHECKS for libraries])
|
||||
|
||||
@@ -11,8 +11,8 @@ emacsdir = $(prefix)/share/emacs/site-lisp
|
||||
all: $(ELC)
|
||||
|
||||
install: all
|
||||
$(INSTALL) -d $(emacsdir)
|
||||
$(INSTALL_ELC) $(ELC) $(emacsdir)
|
||||
$(INSTALL) -d $(DESTDIR)$(emacsdir)
|
||||
$(INSTALL_ELC) $(ELC) $(DESTDIR)$(emacsdir)
|
||||
|
||||
%.elc: %.el
|
||||
$(EMACS) -batch -f batch-byte-compile $<
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
;; License: GPL
|
||||
;; Keywords: git, version control, release management
|
||||
;;
|
||||
;; Compatibility: Emacs21
|
||||
|
||||
;; Compatibility: Emacs21, Emacs22 and EmacsCVS
|
||||
;; Git 1.5 and up
|
||||
|
||||
;; This file is *NOT* part of GNU Emacs.
|
||||
;; This file is distributed under the same terms as GNU Emacs.
|
||||
@@ -61,8 +61,9 @@
|
||||
|
||||
;;; Compatibility:
|
||||
;;
|
||||
;; It requires GNU Emacs 21. If you'are using Emacs 20, try
|
||||
;; changing this:
|
||||
;; It requires GNU Emacs 21 or later and Git 1.5.0 and up
|
||||
;;
|
||||
;; If you'are using Emacs 20, try changing this:
|
||||
;;
|
||||
;; (overlay-put ovl 'face (list :background
|
||||
;; (cdr (assq 'color (cddddr info)))))
|
||||
@@ -77,30 +78,51 @@
|
||||
;;
|
||||
;;; Code:
|
||||
|
||||
(require 'cl) ; to use `push', `pop'
|
||||
(eval-when-compile (require 'cl)) ; to use `push', `pop'
|
||||
|
||||
(defun color-scale (l)
|
||||
(let* ((colors ())
|
||||
r g b)
|
||||
(setq r l)
|
||||
(while r
|
||||
(setq g l)
|
||||
(while g
|
||||
(setq b l)
|
||||
(while b
|
||||
(push (concat "#" (car r) (car g) (car b)) colors)
|
||||
(pop b))
|
||||
(pop g))
|
||||
(pop r))
|
||||
colors))
|
||||
|
||||
(defun git-blame-color-scale (&rest elements)
|
||||
"Given a list, returns a list of triples formed with each
|
||||
elements of the list.
|
||||
|
||||
a b => bbb bba bab baa abb aba aaa aab"
|
||||
(let (result)
|
||||
(dolist (a elements)
|
||||
(dolist (b elements)
|
||||
(dolist (c elements)
|
||||
(setq result (cons (format "#%s%s%s" a b c) result)))))
|
||||
result))
|
||||
|
||||
;; (git-blame-color-scale "0c" "04" "24" "1c" "2c" "34" "14" "3c") =>
|
||||
;; ("#3c3c3c" "#3c3c14" "#3c3c34" "#3c3c2c" "#3c3c1c" "#3c3c24"
|
||||
;; "#3c3c04" "#3c3c0c" "#3c143c" "#3c1414" "#3c1434" "#3c142c" ...)
|
||||
|
||||
(defmacro git-blame-random-pop (l)
|
||||
"Select a random element from L and returns it. Also remove
|
||||
selected element from l."
|
||||
;; only works on lists with unique elements
|
||||
`(let ((e (elt ,l (random (length ,l)))))
|
||||
(setq ,l (remove e ,l))
|
||||
e))
|
||||
|
||||
(defvar git-blame-dark-colors
|
||||
(color-scale '("0c" "04" "24" "1c" "2c" "34" "14" "3c")))
|
||||
(git-blame-color-scale "0c" "04" "24" "1c" "2c" "34" "14" "3c")
|
||||
"*List of colors (format #RGB) to use in a dark environment.
|
||||
|
||||
To check out the list, evaluate (list-colors-display git-blame-dark-colors).")
|
||||
|
||||
(defvar git-blame-light-colors
|
||||
(color-scale '("c4" "d4" "cc" "dc" "f4" "e4" "fc" "ec")))
|
||||
(git-blame-color-scale "c4" "d4" "cc" "dc" "f4" "e4" "fc" "ec")
|
||||
"*List of colors (format #RGB) to use in a light environment.
|
||||
|
||||
(defvar git-blame-ancient-color "dark green")
|
||||
To check out the list, evaluate (list-colors-display git-blame-light-colors).")
|
||||
|
||||
(defvar git-blame-colors '()
|
||||
"Colors used by git-blame. The list is built once when activating git-blame
|
||||
minor mode.")
|
||||
|
||||
(defvar git-blame-ancient-color "dark green"
|
||||
"*Color to be used for ancient commit.")
|
||||
|
||||
(defvar git-blame-autoupdate t
|
||||
"*Automatically update the blame display while editing")
|
||||
@@ -125,41 +147,64 @@
|
||||
"A queue of update requests")
|
||||
(make-variable-buffer-local 'git-blame-update-queue)
|
||||
|
||||
;; FIXME: docstrings
|
||||
(defvar git-blame-file nil)
|
||||
(defvar git-blame-current nil)
|
||||
|
||||
(defvar git-blame-mode nil)
|
||||
(make-variable-buffer-local 'git-blame-mode)
|
||||
(unless (assq 'git-blame-mode minor-mode-alist)
|
||||
(setq minor-mode-alist
|
||||
(cons (list 'git-blame-mode " blame")
|
||||
minor-mode-alist)))
|
||||
|
||||
(defvar git-blame-mode-line-string " blame"
|
||||
"String to display on the mode line when git-blame is active.")
|
||||
|
||||
(or (assq 'git-blame-mode minor-mode-alist)
|
||||
(setq minor-mode-alist
|
||||
(cons '(git-blame-mode git-blame-mode-line-string) minor-mode-alist)))
|
||||
|
||||
;;;###autoload
|
||||
(defun git-blame-mode (&optional arg)
|
||||
"Minor mode for displaying Git blame"
|
||||
"Toggle minor mode for displaying Git blame
|
||||
|
||||
With prefix ARG, turn the mode on if ARG is positive."
|
||||
(interactive "P")
|
||||
(if arg
|
||||
(setq git-blame-mode (eq arg 1))
|
||||
(setq git-blame-mode (not git-blame-mode)))
|
||||
(cond
|
||||
((null arg)
|
||||
(if git-blame-mode (git-blame-mode-off) (git-blame-mode-on)))
|
||||
((> (prefix-numeric-value arg) 0) (git-blame-mode-on))
|
||||
(t (git-blame-mode-off))))
|
||||
|
||||
(defun git-blame-mode-on ()
|
||||
"Turn on git-blame mode.
|
||||
|
||||
See also function `git-blame-mode'."
|
||||
(make-local-variable 'git-blame-colors)
|
||||
(if git-blame-autoupdate
|
||||
(add-hook 'after-change-functions 'git-blame-after-change nil t)
|
||||
(remove-hook 'after-change-functions 'git-blame-after-change t))
|
||||
(git-blame-cleanup)
|
||||
(if git-blame-mode
|
||||
(progn
|
||||
(let ((bgmode (cdr (assoc 'background-mode (frame-parameters)))))
|
||||
(if (eq bgmode 'dark)
|
||||
(setq git-blame-colors git-blame-dark-colors)
|
||||
(setq git-blame-colors git-blame-light-colors)))
|
||||
(setq git-blame-cache (make-hash-table :test 'equal))
|
||||
(git-blame-run))
|
||||
(cancel-timer git-blame-idle-timer)))
|
||||
(let ((bgmode (cdr (assoc 'background-mode (frame-parameters)))))
|
||||
(if (eq bgmode 'dark)
|
||||
(setq git-blame-colors git-blame-dark-colors)
|
||||
(setq git-blame-colors git-blame-light-colors)))
|
||||
(setq git-blame-cache (make-hash-table :test 'equal))
|
||||
(setq git-blame-mode t)
|
||||
(git-blame-run))
|
||||
|
||||
(defun git-blame-mode-off ()
|
||||
"Turn off git-blame mode.
|
||||
|
||||
See also function `git-blame-mode'."
|
||||
(git-blame-cleanup)
|
||||
(if git-blame-idle-timer (cancel-timer git-blame-idle-timer))
|
||||
(setq git-blame-mode nil))
|
||||
|
||||
;;;###autoload
|
||||
(defun git-reblame ()
|
||||
"Recalculate all blame information in the current buffer"
|
||||
(unless git-blame-mode
|
||||
(error "git-blame is not active"))
|
||||
(interactive)
|
||||
(unless git-blame-mode
|
||||
(error "Git-blame is not active"))
|
||||
|
||||
(git-blame-cleanup)
|
||||
(git-blame-run))
|
||||
|
||||
@@ -275,7 +320,6 @@
|
||||
(t
|
||||
nil)))
|
||||
|
||||
|
||||
(defun git-blame-new-commit (hash src-line res-line num-lines)
|
||||
(save-excursion
|
||||
(set-buffer git-blame-file)
|
||||
@@ -283,9 +327,11 @@
|
||||
(inhibit-point-motion-hooks t)
|
||||
(inhibit-modification-hooks t))
|
||||
(when (not info)
|
||||
(let ((color (pop git-blame-colors)))
|
||||
(unless color
|
||||
(setq color git-blame-ancient-color))
|
||||
;; Assign a random color to each new commit info
|
||||
;; Take care not to select the same color multiple times
|
||||
(let ((color (if git-blame-colors
|
||||
(git-blame-random-pop git-blame-colors)
|
||||
git-blame-ancient-color)))
|
||||
(setq info (list hash src-line res-line num-lines
|
||||
(git-describe-commit hash)
|
||||
(cons 'color color))))
|
||||
|
||||
13
diff.c
13
diff.c
@@ -812,7 +812,12 @@ static void show_stats(struct diffstat_t* data, struct diff_options *options)
|
||||
|
||||
if (data->files[i]->is_binary) {
|
||||
show_name(prefix, name, len, reset, set);
|
||||
printf(" Bin\n");
|
||||
printf(" Bin ");
|
||||
printf("%s%d%s", del_c, deleted, reset);
|
||||
printf(" -> ");
|
||||
printf("%s%d%s", add_c, added, reset);
|
||||
printf(" bytes");
|
||||
printf("\n");
|
||||
goto free_diffstat_file;
|
||||
}
|
||||
else if (data->files[i]->is_unmerged) {
|
||||
@@ -1186,9 +1191,11 @@ static void builtin_diffstat(const char *name_a, const char *name_b,
|
||||
if (fill_mmfile(&mf1, one) < 0 || fill_mmfile(&mf2, two) < 0)
|
||||
die("unable to read files to diff");
|
||||
|
||||
if (mmfile_is_binary(&mf1) || mmfile_is_binary(&mf2))
|
||||
if (mmfile_is_binary(&mf1) || mmfile_is_binary(&mf2)) {
|
||||
data->is_binary = 1;
|
||||
else {
|
||||
data->added = mf2.size;
|
||||
data->deleted = mf1.size;
|
||||
} else {
|
||||
/* Crazy xdl interfaces.. */
|
||||
xpparam_t xpp;
|
||||
xdemitconf_t xecfg;
|
||||
|
||||
96
dir.c
96
dir.c
@@ -8,6 +8,11 @@
|
||||
#include "cache.h"
|
||||
#include "dir.h"
|
||||
|
||||
struct path_simplify {
|
||||
int len;
|
||||
const char *path;
|
||||
};
|
||||
|
||||
int common_prefix(const char **pathspec)
|
||||
{
|
||||
const char *path, *slash, *next;
|
||||
@@ -292,6 +297,31 @@ static int dir_exists(const char *dirname, int len)
|
||||
return !strncmp(active_cache[pos]->name, dirname, len);
|
||||
}
|
||||
|
||||
/*
|
||||
* This is an inexact early pruning of any recursive directory
|
||||
* reading - if the path cannot possibly be in the pathspec,
|
||||
* return true, and we'll skip it early.
|
||||
*/
|
||||
static int simplify_away(const char *path, int pathlen, const struct path_simplify *simplify)
|
||||
{
|
||||
if (simplify) {
|
||||
for (;;) {
|
||||
const char *match = simplify->path;
|
||||
int len = simplify->len;
|
||||
|
||||
if (!match)
|
||||
break;
|
||||
if (len > pathlen)
|
||||
len = pathlen;
|
||||
if (!memcmp(path, match, len))
|
||||
return 0;
|
||||
simplify++;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read a directory tree. We currently ignore anything but
|
||||
* directories, regular files and symlinks. That's because git
|
||||
@@ -301,7 +331,7 @@ static int dir_exists(const char *dirname, int len)
|
||||
* Also, we ignore the name ".git" (even if it is not a directory).
|
||||
* That likely will not change.
|
||||
*/
|
||||
static int read_directory_recursive(struct dir_struct *dir, const char *path, const char *base, int baselen, int check_only)
|
||||
static int read_directory_recursive(struct dir_struct *dir, const char *path, const char *base, int baselen, int check_only, const struct path_simplify *simplify)
|
||||
{
|
||||
DIR *fdir = opendir(path);
|
||||
int contents = 0;
|
||||
@@ -324,6 +354,8 @@ static int read_directory_recursive(struct dir_struct *dir, const char *path, co
|
||||
continue;
|
||||
len = strlen(de->d_name);
|
||||
memcpy(fullname + baselen, de->d_name, len+1);
|
||||
if (simplify_away(fullname, baselen + len, simplify))
|
||||
continue;
|
||||
if (excluded(dir, fullname) != dir->show_ignored) {
|
||||
if (!dir->show_ignored || DTYPE(de) != DT_DIR) {
|
||||
continue;
|
||||
@@ -350,13 +382,13 @@ static int read_directory_recursive(struct dir_struct *dir, const char *path, co
|
||||
if (dir->hide_empty_directories &&
|
||||
!read_directory_recursive(dir,
|
||||
fullname, fullname,
|
||||
baselen + len, 1))
|
||||
baselen + len, 1, simplify))
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
|
||||
contents += read_directory_recursive(dir,
|
||||
fullname, fullname, baselen + len, 0);
|
||||
fullname, fullname, baselen + len, 0, simplify);
|
||||
continue;
|
||||
case DT_REG:
|
||||
case DT_LNK:
|
||||
@@ -386,8 +418,61 @@ static int cmp_name(const void *p1, const void *p2)
|
||||
e2->name, e2->len);
|
||||
}
|
||||
|
||||
int read_directory(struct dir_struct *dir, const char *path, const char *base, int baselen)
|
||||
/*
|
||||
* Return the length of the "simple" part of a path match limiter.
|
||||
*/
|
||||
static int simple_length(const char *match)
|
||||
{
|
||||
const char special[256] = {
|
||||
[0] = 1, ['?'] = 1,
|
||||
['\\'] = 1, ['*'] = 1,
|
||||
['['] = 1
|
||||
};
|
||||
int len = -1;
|
||||
|
||||
for (;;) {
|
||||
unsigned char c = *match++;
|
||||
len++;
|
||||
if (special[c])
|
||||
return len;
|
||||
}
|
||||
}
|
||||
|
||||
static struct path_simplify *create_simplify(const char **pathspec)
|
||||
{
|
||||
int nr, alloc = 0;
|
||||
struct path_simplify *simplify = NULL;
|
||||
|
||||
if (!pathspec)
|
||||
return NULL;
|
||||
|
||||
for (nr = 0 ; ; nr++) {
|
||||
const char *match;
|
||||
if (nr >= alloc) {
|
||||
alloc = alloc_nr(alloc);
|
||||
simplify = xrealloc(simplify, alloc * sizeof(*simplify));
|
||||
}
|
||||
match = *pathspec++;
|
||||
if (!match)
|
||||
break;
|
||||
simplify[nr].path = match;
|
||||
simplify[nr].len = simple_length(match);
|
||||
}
|
||||
simplify[nr].path = NULL;
|
||||
simplify[nr].len = 0;
|
||||
return simplify;
|
||||
}
|
||||
|
||||
static void free_simplify(struct path_simplify *simplify)
|
||||
{
|
||||
if (simplify)
|
||||
free(simplify);
|
||||
}
|
||||
|
||||
int read_directory(struct dir_struct *dir, const char *path, const char *base, int baselen, const char **pathspec)
|
||||
{
|
||||
struct path_simplify *simplify = create_simplify(pathspec);
|
||||
|
||||
/*
|
||||
* Make sure to do the per-directory exclude for all the
|
||||
* directories leading up to our base.
|
||||
@@ -414,7 +499,8 @@ int read_directory(struct dir_struct *dir, const char *path, const char *base, i
|
||||
}
|
||||
}
|
||||
|
||||
read_directory_recursive(dir, path, base, baselen, 0);
|
||||
read_directory_recursive(dir, path, base, baselen, 0, simplify);
|
||||
free_simplify(simplify);
|
||||
qsort(dir->entries, dir->nr, sizeof(struct dir_entry *), cmp_name);
|
||||
return dir->nr;
|
||||
}
|
||||
|
||||
2
dir.h
2
dir.h
@@ -48,7 +48,7 @@ extern int common_prefix(const char **pathspec);
|
||||
#define MATCHED_EXACTLY 3
|
||||
extern int match_pathspec(const char **pathspec, const char *name, int namelen, int prefix, char *seen);
|
||||
|
||||
extern int read_directory(struct dir_struct *, const char *path, const char *base, int baselen);
|
||||
extern int read_directory(struct dir_struct *, const char *path, const char *base, int baselen, const char **pathspec);
|
||||
extern int push_exclude_per_directory(struct dir_struct *, const char *, int);
|
||||
extern void pop_exclude_per_directory(struct dir_struct *, int);
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ fi
|
||||
laf="$GIT_DIR/lost-found"
|
||||
rm -fr "$laf" && mkdir -p "$laf/commit" "$laf/other" || exit
|
||||
|
||||
git fsck --full |
|
||||
git fsck --full --no-reflogs |
|
||||
while read dangling type sha1
|
||||
do
|
||||
case "$dangling" in
|
||||
|
||||
@@ -33,7 +33,7 @@ use Carp qw/croak/;
|
||||
use IO::File qw//;
|
||||
use File::Basename qw/dirname basename/;
|
||||
use File::Path qw/mkpath/;
|
||||
use Getopt::Long qw/:config gnu_getopt no_ignore_case auto_abbrev pass_through/;
|
||||
use Getopt::Long qw/:config gnu_getopt no_ignore_case auto_abbrev/;
|
||||
use IPC::Open3;
|
||||
use Git;
|
||||
|
||||
@@ -168,6 +168,7 @@ for (my $i = 0; $i < @ARGV; $i++) {
|
||||
my %opts = %{$cmd{$cmd}->[2]} if (defined $cmd);
|
||||
|
||||
read_repo_config(\%opts);
|
||||
Getopt::Long::Configure('pass_through') if $cmd eq 'log';
|
||||
my $rv = GetOptions(%opts, 'help|H|h' => \$_help, 'version|V' => \$_version,
|
||||
'minimize-connections' => \$Git::SVN::Migration::_minimize,
|
||||
'id|i=s' => \$Git::SVN::default_ref_id,
|
||||
@@ -229,6 +230,8 @@ Usage: $0 <command> [options] [arguments]\n
|
||||
next if /^multi-/; # don't show deprecated commands
|
||||
print $fd ' ',pack('A17',$_),$cmd{$_}->[1],"\n";
|
||||
foreach (keys %{$cmd{$_}->[2]}) {
|
||||
# mixed-case options are for .git/config only
|
||||
next if /[A-Z]/ && /^[a-z]+$/i;
|
||||
# prints out arguments as they should be passed:
|
||||
my $x = s#[:=]s$## ? '<arg>' : s#[:=]i$## ? '<num>' : '';
|
||||
print $fd ' ' x 21, join(', ', map { length $_ > 1 ?
|
||||
|
||||
2
git.c
2
git.c
@@ -230,7 +230,7 @@ static void handle_internal_command(int argc, const char **argv, char **envp)
|
||||
{ "add", cmd_add, RUN_SETUP | NOT_BARE },
|
||||
{ "annotate", cmd_annotate, USE_PAGER },
|
||||
{ "apply", cmd_apply },
|
||||
{ "archive", cmd_archive, RUN_SETUP },
|
||||
{ "archive", cmd_archive },
|
||||
{ "blame", cmd_blame, RUN_SETUP },
|
||||
{ "branch", cmd_branch, RUN_SETUP },
|
||||
{ "bundle", cmd_bundle },
|
||||
|
||||
36
git.spec.in
36
git.spec.in
@@ -1,4 +1,7 @@
|
||||
# Pass --without docs to rpmbuild if you don't want the documentation
|
||||
|
||||
%define python_path /usr/bin/python
|
||||
|
||||
Name: git
|
||||
Version: @@VERSION@@
|
||||
Release: 1%{?dist}
|
||||
@@ -9,7 +12,7 @@ URL: http://kernel.org/pub/software/scm/git/
|
||||
Source: http://kernel.org/pub/software/scm/git/%{name}-%{version}.tar.gz
|
||||
BuildRequires: zlib-devel >= 1.2, openssl-devel, curl-devel, expat-devel %{!?_without_docs:, xmlto, asciidoc > 6.0.3}
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
|
||||
Requires: git-core, git-svn, git-cvs, git-arch, git-email, gitk, git-gui, perl-Git
|
||||
Requires: git-core, git-svn, git-cvs, git-arch, git-email, gitk, git-gui, git-p4, perl-Git
|
||||
|
||||
%description
|
||||
Git is a fast, scalable, distributed revision control system with an
|
||||
@@ -50,6 +53,13 @@ Requires: git-core = %{version}-%{release}, tla
|
||||
%description arch
|
||||
Git tools for importing Arch repositories.
|
||||
|
||||
%package p4
|
||||
Summary: Git tools for importing Perforce repositories
|
||||
Group: Development/Tools
|
||||
Requires: git-core = %{version}-%{release}, python
|
||||
%description p4
|
||||
Git tools for importing Perforce repositories.
|
||||
|
||||
%package email
|
||||
Summary: Git tools for sending email
|
||||
Group: Development/Tools
|
||||
@@ -85,23 +95,23 @@ Perl interface to Git
|
||||
%setup -q
|
||||
|
||||
%build
|
||||
make %{_smp_mflags} CFLAGS="$RPM_OPT_FLAGS" WITH_OWN_SUBPROCESS_PY=YesPlease \
|
||||
prefix=%{_prefix} all %{!?_without_docs: doc}
|
||||
make %{_smp_mflags} CFLAGS="$RPM_OPT_FLAGS" WITH_P4IMPORT=YesPlease \
|
||||
prefix=%{_prefix} PYTHON_PATH=%{python_path} all %{!?_without_docs: doc}
|
||||
|
||||
%install
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
make %{_smp_mflags} CFLAGS="$RPM_OPT_FLAGS" DESTDIR=$RPM_BUILD_ROOT \
|
||||
WITH_OWN_SUBPROCESS_PY=YesPlease \
|
||||
prefix=%{_prefix} mandir=%{_mandir} INSTALLDIRS=vendor \
|
||||
install %{!?_without_docs: install-doc}
|
||||
WITH_P4IMPORT=YesPlease prefix=%{_prefix} mandir=%{_mandir} \
|
||||
PYTHON_PATH=%{python_path} \
|
||||
INSTALLDIRS=vendor install %{!?_without_docs: install-doc}
|
||||
find $RPM_BUILD_ROOT -type f -name .packlist -exec rm -f {} ';'
|
||||
find $RPM_BUILD_ROOT -type f -name '*.bs' -empty -exec rm -f {} ';'
|
||||
find $RPM_BUILD_ROOT -type f -name perllocal.pod -exec rm -f {} ';'
|
||||
|
||||
(find $RPM_BUILD_ROOT%{_bindir} -type f | grep -vE "archimport|svn|cvs|email|gitk|git-gui|git-citool" | sed -e s@^$RPM_BUILD_ROOT@@) > bin-man-doc-files
|
||||
(find $RPM_BUILD_ROOT%{_bindir} -type f | grep -vE "p4import|archimport|svn|cvs|email|gitk|git-gui|git-citool" | sed -e s@^$RPM_BUILD_ROOT@@) > bin-man-doc-files
|
||||
(find $RPM_BUILD_ROOT%{perl_vendorlib} -type f | sed -e s@^$RPM_BUILD_ROOT@@) >> perl-files
|
||||
%if %{!?_without_docs:1}0
|
||||
(find $RPM_BUILD_ROOT%{_mandir} $RPM_BUILD_ROOT/Documentation -type f | grep -vE "archimport|svn|git-cvs|email|gitk|git-gui|git-citool" | sed -e s@^$RPM_BUILD_ROOT@@ -e 's/$/*/' ) >> bin-man-doc-files
|
||||
(find $RPM_BUILD_ROOT%{_mandir} $RPM_BUILD_ROOT/Documentation -type f | grep -vE "p4import|archimport|svn|git-cvs|email|gitk|git-gui|git-citool" | sed -e s@^$RPM_BUILD_ROOT@@ -e 's/$/*/' ) >> bin-man-doc-files
|
||||
%else
|
||||
rm -rf $RPM_BUILD_ROOT%{_mandir}
|
||||
%endif
|
||||
@@ -133,6 +143,13 @@ rm -rf $RPM_BUILD_ROOT
|
||||
%{!?_without_docs: %{_mandir}/man1/git-archimport.1*}
|
||||
%{!?_without_docs: %doc Documentation/git-archimport.html }
|
||||
|
||||
%files p4
|
||||
%defattr(-,root,root)
|
||||
%doc Documentation/git-p4import.txt
|
||||
%{_bindir}/git-p4import
|
||||
%{!?_without_docs: %{_mandir}/man1/git-p4import.1*}
|
||||
%{!?_without_docs: %doc Documentation/git-p4import.html }
|
||||
|
||||
%files email
|
||||
%defattr(-,root,root)
|
||||
%doc Documentation/*email*.txt
|
||||
@@ -167,6 +184,9 @@ rm -rf $RPM_BUILD_ROOT
|
||||
%{!?_without_docs: %doc Documentation/*.html }
|
||||
|
||||
%changelog
|
||||
* Tue Mar 27 2007 Eygene Ryabinkin <rea-git@codelabs.ru>
|
||||
- Added the git-p4 package: Perforce import stuff.
|
||||
|
||||
* Mon Feb 13 2007 Nicolas Pitre <nico@cam.org>
|
||||
- Update core package description (Git isn't as stupid as it used to be)
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ use File::Basename qw(basename);
|
||||
binmode STDOUT, ':utf8';
|
||||
|
||||
BEGIN {
|
||||
CGI->compile() if $ENV{MOD_PERL};
|
||||
CGI->compile() if $ENV{'MOD_PERL'};
|
||||
}
|
||||
|
||||
our $cgi = new CGI;
|
||||
@@ -1800,7 +1800,7 @@ EOF
|
||||
$cgi->hidden(-name => "a") . "\n" .
|
||||
$cgi->hidden(-name => "h") . "\n" .
|
||||
$cgi->popup_menu(-name => 'st', -default => 'commit',
|
||||
-values => ['commit', 'author', 'committer', 'pickaxe']) .
|
||||
-values => ['commit', 'author', 'committer', 'pickaxe']) .
|
||||
$cgi->sup($cgi->a({-href => href(action=>"search_help")}, "?")) .
|
||||
" search:\n",
|
||||
$cgi->textfield(-name => "s", -value => $searchtext) . "\n" .
|
||||
@@ -1870,16 +1870,16 @@ sub git_print_page_nav {
|
||||
my %arg = map { $_ => {action=>$_} } @navs;
|
||||
if (defined $head) {
|
||||
for (qw(commit commitdiff)) {
|
||||
$arg{$_}{hash} = $head;
|
||||
$arg{$_}{'hash'} = $head;
|
||||
}
|
||||
if ($current =~ m/^(tree | log | shortlog | commit | commitdiff | search)$/x) {
|
||||
for (qw(shortlog log)) {
|
||||
$arg{$_}{hash} = $head;
|
||||
$arg{$_}{'hash'} = $head;
|
||||
}
|
||||
}
|
||||
}
|
||||
$arg{tree}{hash} = $treehead if defined $treehead;
|
||||
$arg{tree}{hash_base} = $treebase if defined $treebase;
|
||||
$arg{'tree'}{'hash'} = $treehead if defined $treehead;
|
||||
$arg{'tree'}{'hash_base'} = $treebase if defined $treebase;
|
||||
|
||||
print "<div class=\"page_nav\">\n" .
|
||||
(join " | ",
|
||||
@@ -1927,9 +1927,9 @@ sub git_print_header_div {
|
||||
my ($action, $title, $hash, $hash_base) = @_;
|
||||
my %args = ();
|
||||
|
||||
$args{action} = $action;
|
||||
$args{hash} = $hash if $hash;
|
||||
$args{hash_base} = $hash_base if $hash_base;
|
||||
$args{'action'} = $action;
|
||||
$args{'hash'} = $hash if $hash;
|
||||
$args{'hash_base'} = $hash_base if $hash_base;
|
||||
|
||||
print "<div class=\"header\">\n" .
|
||||
$cgi->a({-href => href(%args), -class => "title"},
|
||||
@@ -3095,7 +3095,7 @@ sub git_summary {
|
||||
git_project_list_body(\@forklist, undef, 0, 15,
|
||||
$#forklist <= 15 ? undef :
|
||||
$cgi->a({-href => href(action=>"forks")}, "..."),
|
||||
'noheader');
|
||||
'noheader');
|
||||
}
|
||||
|
||||
git_footer_html();
|
||||
@@ -3202,7 +3202,7 @@ HTML
|
||||
my $rev = substr($full_rev, 0, 8);
|
||||
my $author = $meta->{'author'};
|
||||
my %date = parse_date($meta->{'author-time'},
|
||||
$meta->{'author-tz'});
|
||||
$meta->{'author-tz'});
|
||||
my $date = $date{'iso-tz'};
|
||||
if ($group_size) {
|
||||
$current_color = ++$current_color % $num_colors;
|
||||
@@ -3214,9 +3214,9 @@ HTML
|
||||
print " rowspan=\"$group_size\"" if ($group_size > 1);
|
||||
print ">";
|
||||
print $cgi->a({-href => href(action=>"commit",
|
||||
hash=>$full_rev,
|
||||
file_name=>$file_name)},
|
||||
esc_html($rev));
|
||||
hash=>$full_rev,
|
||||
file_name=>$file_name)},
|
||||
esc_html($rev));
|
||||
print "</td>\n";
|
||||
}
|
||||
open (my $dd, "-|", git_cmd(), "rev-parse", "$full_rev^")
|
||||
@@ -3225,13 +3225,13 @@ HTML
|
||||
close $dd;
|
||||
chomp($parent_commit);
|
||||
my $blamed = href(action => 'blame',
|
||||
file_name => $meta->{'filename'},
|
||||
hash_base => $parent_commit);
|
||||
file_name => $meta->{'filename'},
|
||||
hash_base => $parent_commit);
|
||||
print "<td class=\"linenr\">";
|
||||
print $cgi->a({ -href => "$blamed#l$orig_lineno",
|
||||
-id => "l$lineno",
|
||||
-class => "linenr" },
|
||||
esc_html($lineno));
|
||||
-id => "l$lineno",
|
||||
-class => "linenr" },
|
||||
esc_html($lineno));
|
||||
print "</td>";
|
||||
print "<td class=\"pre\">" . esc_html($data) . "</td>\n";
|
||||
print "</tr>\n";
|
||||
@@ -3621,7 +3621,7 @@ sub git_snapshot {
|
||||
my $name = $project;
|
||||
$name =~ s/\047/\047\\\047\047/g;
|
||||
open my $fd, "-|",
|
||||
"$git archive --format=tar --prefix=\'$name\'/ $hash | $command"
|
||||
"$git archive --format=tar --prefix=\'$name\'/ $hash | $command"
|
||||
or die_error(undef, "Execute git-tar-tree failed");
|
||||
binmode STDOUT, ':raw';
|
||||
print <$fd>;
|
||||
@@ -3734,7 +3734,7 @@ sub git_commit {
|
||||
# difftree output is not printed for merges
|
||||
open my $fd, "-|", git_cmd(), "diff-tree", '-r', "--no-commit-id",
|
||||
@diff_opts, $parent, $hash, "--"
|
||||
or die_error(undef, "Open git-diff-tree failed");
|
||||
or die_error(undef, "Open git-diff-tree failed");
|
||||
@difftree = map { chomp; $_ } <$fd>;
|
||||
close $fd or die_error(undef, "Reading git-diff-tree failed");
|
||||
}
|
||||
@@ -3934,7 +3934,8 @@ sub git_blobdiff {
|
||||
|
||||
# open patch output
|
||||
open $fd, "-|", git_cmd(), "diff-tree", '-r', @diff_opts,
|
||||
'-p', $hash_parent_base, $hash_base,
|
||||
'-p', ($format eq 'html' ? "--full-index" : ()),
|
||||
$hash_parent_base, $hash_base,
|
||||
"--", (defined $file_parent ? $file_parent : ()), $file_name
|
||||
or die_error(undef, "Open git-diff-tree failed");
|
||||
}
|
||||
@@ -3969,7 +3970,8 @@ sub git_blobdiff {
|
||||
}
|
||||
|
||||
# open patch output
|
||||
open $fd, "-|", git_cmd(), "diff", '-p', @diff_opts,
|
||||
open $fd, "-|", git_cmd(), "diff", @diff_opts,
|
||||
'-p', ($format eq 'html' ? "--full-index" : ()),
|
||||
$hash_parent, $hash, "--"
|
||||
or die_error(undef, "Open git-diff failed");
|
||||
} else {
|
||||
@@ -4304,13 +4306,13 @@ sub git_search {
|
||||
if ($page > 0) {
|
||||
$paging_nav .=
|
||||
$cgi->a({-href => href(action=>"search", hash=>$hash,
|
||||
searchtext=>$searchtext, searchtype=>$searchtype)},
|
||||
"first");
|
||||
searchtext=>$searchtext, searchtype=>$searchtype)},
|
||||
"first");
|
||||
$paging_nav .= " ⋅ " .
|
||||
$cgi->a({-href => href(action=>"search", hash=>$hash,
|
||||
searchtext=>$searchtext, searchtype=>$searchtype,
|
||||
page=>$page-1),
|
||||
-accesskey => "p", -title => "Alt-p"}, "prev");
|
||||
searchtext=>$searchtext, searchtype=>$searchtype,
|
||||
page=>$page-1),
|
||||
-accesskey => "p", -title => "Alt-p"}, "prev");
|
||||
} else {
|
||||
$paging_nav .= "first";
|
||||
$paging_nav .= " ⋅ prev";
|
||||
@@ -4318,9 +4320,9 @@ sub git_search {
|
||||
if ($#commitlist >= 100) {
|
||||
$paging_nav .= " ⋅ " .
|
||||
$cgi->a({-href => href(action=>"search", hash=>$hash,
|
||||
searchtext=>$searchtext, searchtype=>$searchtype,
|
||||
page=>$page+1),
|
||||
-accesskey => "n", -title => "Alt-n"}, "next");
|
||||
searchtext=>$searchtext, searchtype=>$searchtype,
|
||||
page=>$page+1),
|
||||
-accesskey => "n", -title => "Alt-n"}, "next");
|
||||
} else {
|
||||
$paging_nav .= " ⋅ next";
|
||||
}
|
||||
@@ -4328,9 +4330,9 @@ sub git_search {
|
||||
if ($#commitlist >= 100) {
|
||||
$next_link =
|
||||
$cgi->a({-href => href(action=>"search", hash=>$hash,
|
||||
searchtext=>$searchtext, searchtype=>$searchtype,
|
||||
page=>$page+1),
|
||||
-accesskey => "n", -title => "Alt-n"}, "next");
|
||||
searchtext=>$searchtext, searchtype=>$searchtype,
|
||||
page=>$page+1),
|
||||
-accesskey => "n", -title => "Alt-n"}, "next");
|
||||
}
|
||||
|
||||
git_print_page_nav('','', $hash,$co{'tree'},$hash, $paging_nav);
|
||||
|
||||
@@ -198,7 +198,7 @@ static void start_object_request(struct object_request *obj_req)
|
||||
SHA1_Init(&obj_req->c);
|
||||
if (prev_posn>0) {
|
||||
prev_posn = 0;
|
||||
lseek(obj_req->local, SEEK_SET, 0);
|
||||
lseek(obj_req->local, 0, SEEK_SET);
|
||||
ftruncate(obj_req->local, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -312,7 +312,7 @@ static void start_fetch_loose(struct transfer_request *request)
|
||||
SHA1_Init(&request->c);
|
||||
if (prev_posn>0) {
|
||||
prev_posn = 0;
|
||||
lseek(request->local_fileno, SEEK_SET, 0);
|
||||
lseek(request->local_fileno, 0, SEEK_SET);
|
||||
ftruncate(request->local_fileno, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -221,7 +221,7 @@ static int add_cacheinfo(unsigned int mode, const unsigned char *sha1,
|
||||
struct cache_entry *ce;
|
||||
ce = make_cache_entry(mode, sha1 ? sha1 : null_sha1, path, stage, refresh);
|
||||
if (!ce)
|
||||
return error("cache_addinfo failed: %s", strerror(cache_errno));
|
||||
return error("addinfo_cache failed for path '%s'", path);
|
||||
return add_cache_entry(ce, options);
|
||||
}
|
||||
|
||||
|
||||
11
pack-check.c
11
pack-check.c
@@ -42,13 +42,14 @@ static int verify_packfile(struct packed_git *p,
|
||||
*/
|
||||
nr_objects = num_packed_objects(p);
|
||||
for (i = 0, err = 0; i < nr_objects; i++) {
|
||||
unsigned char sha1[20];
|
||||
const unsigned char *sha1;
|
||||
void *data;
|
||||
enum object_type type;
|
||||
unsigned long size;
|
||||
off_t offset;
|
||||
|
||||
if (nth_packed_object_sha1(p, i, sha1))
|
||||
sha1 = nth_packed_object_sha1(p, i);
|
||||
if (!sha1)
|
||||
die("internal error pack-check nth-packed-object");
|
||||
offset = find_pack_entry_one(sha1, p);
|
||||
if (!offset)
|
||||
@@ -82,14 +83,16 @@ static void show_pack_info(struct packed_git *p)
|
||||
memset(chain_histogram, 0, sizeof(chain_histogram));
|
||||
|
||||
for (i = 0; i < nr_objects; i++) {
|
||||
unsigned char sha1[20], base_sha1[20];
|
||||
const unsigned char *sha1;
|
||||
unsigned char base_sha1[20];
|
||||
const char *type;
|
||||
unsigned long size;
|
||||
unsigned long store_size;
|
||||
off_t offset;
|
||||
unsigned int delta_chain_length;
|
||||
|
||||
if (nth_packed_object_sha1(p, i, sha1))
|
||||
sha1 = nth_packed_object_sha1(p, i);
|
||||
if (!sha1)
|
||||
die("internal error pack-check nth-packed-object");
|
||||
offset = find_pack_entry_one(sha1, p);
|
||||
if (!offset)
|
||||
|
||||
21
read-cache.c
21
read-cache.c
@@ -24,8 +24,6 @@ unsigned int active_nr, active_alloc, active_cache_changed;
|
||||
|
||||
struct cache_tree *active_cache_tree;
|
||||
|
||||
int cache_errno;
|
||||
|
||||
static void *cache_mmap;
|
||||
static size_t cache_mmap_size;
|
||||
|
||||
@@ -327,7 +325,7 @@ int remove_file_from_cache(const char *path)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int add_file_to_index(const char *path, int verbose)
|
||||
int add_file_to_cache(const char *path, int verbose)
|
||||
{
|
||||
int size, namelen;
|
||||
struct stat st;
|
||||
@@ -643,14 +641,15 @@ int add_cache_entry(struct cache_entry *ce, int option)
|
||||
* 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.
|
||||
*/
|
||||
struct cache_entry *refresh_cache_entry(struct cache_entry *ce, int really)
|
||||
static struct cache_entry *refresh_cache_ent(struct cache_entry *ce, int really, int *err)
|
||||
{
|
||||
struct stat st;
|
||||
struct cache_entry *updated;
|
||||
int changed, size;
|
||||
|
||||
if (lstat(ce->name, &st) < 0) {
|
||||
cache_errno = errno;
|
||||
if (err)
|
||||
*err = errno;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -664,7 +663,8 @@ struct cache_entry *refresh_cache_entry(struct cache_entry *ce, int really)
|
||||
}
|
||||
|
||||
if (ce_modified(ce, &st, really)) {
|
||||
cache_errno = EINVAL;
|
||||
if (err)
|
||||
*err = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -696,6 +696,8 @@ int refresh_cache(unsigned int flags)
|
||||
|
||||
for (i = 0; i < active_nr; i++) {
|
||||
struct cache_entry *ce, *new;
|
||||
int cache_errno = 0;
|
||||
|
||||
ce = active_cache[i];
|
||||
if (ce_stage(ce)) {
|
||||
while ((i < active_nr) &&
|
||||
@@ -709,7 +711,7 @@ int refresh_cache(unsigned int flags)
|
||||
continue;
|
||||
}
|
||||
|
||||
new = refresh_cache_entry(ce, really);
|
||||
new = refresh_cache_ent(ce, really, &cache_errno);
|
||||
if (new == ce)
|
||||
continue;
|
||||
if (!new) {
|
||||
@@ -737,6 +739,11 @@ int refresh_cache(unsigned int flags)
|
||||
return has_errors;
|
||||
}
|
||||
|
||||
struct cache_entry *refresh_cache_entry(struct cache_entry *ce, int really)
|
||||
{
|
||||
return refresh_cache_ent(ce, really, NULL);
|
||||
}
|
||||
|
||||
static int verify_hdr(struct cache_header *hdr, unsigned long size)
|
||||
{
|
||||
SHA_CTX c;
|
||||
|
||||
@@ -1542,15 +1542,14 @@ uint32_t num_packed_objects(const struct packed_git *p)
|
||||
return (uint32_t)((p->index_size - 20 - 20 - 4*256) / 24);
|
||||
}
|
||||
|
||||
int nth_packed_object_sha1(const struct packed_git *p, uint32_t n,
|
||||
unsigned char* sha1)
|
||||
const unsigned char *nth_packed_object_sha1(const struct packed_git *p,
|
||||
uint32_t n)
|
||||
{
|
||||
const unsigned char *index = p->index_data;
|
||||
index += 4 * 256;
|
||||
if (num_packed_objects(p) <= n)
|
||||
return -1;
|
||||
hashcpy(sha1, index + 24 * n + 4);
|
||||
return 0;
|
||||
return NULL;
|
||||
return index + 24 * n + 4;
|
||||
}
|
||||
|
||||
off_t find_pack_entry_one(const unsigned char *sha1,
|
||||
|
||||
16
sha1_name.c
16
sha1_name.c
@@ -71,7 +71,7 @@ static int match_sha(unsigned len, const unsigned char *a, const unsigned char *
|
||||
static int find_short_packed_object(int len, const unsigned char *match, unsigned char *sha1)
|
||||
{
|
||||
struct packed_git *p;
|
||||
unsigned char found_sha1[20];
|
||||
const unsigned char *found_sha1 = NULL;
|
||||
int found = 0;
|
||||
|
||||
prepare_packed_git();
|
||||
@@ -80,10 +80,10 @@ static int find_short_packed_object(int len, const unsigned char *match, unsigne
|
||||
uint32_t first = 0, last = num;
|
||||
while (first < last) {
|
||||
uint32_t mid = (first + last) / 2;
|
||||
unsigned char now[20];
|
||||
const unsigned char *now;
|
||||
int cmp;
|
||||
|
||||
nth_packed_object_sha1(p, mid, now);
|
||||
now = nth_packed_object_sha1(p, mid);
|
||||
cmp = hashcmp(match, now);
|
||||
if (!cmp) {
|
||||
first = mid;
|
||||
@@ -96,14 +96,14 @@ static int find_short_packed_object(int len, const unsigned char *match, unsigne
|
||||
last = mid;
|
||||
}
|
||||
if (first < num) {
|
||||
unsigned char now[20], next[20];
|
||||
nth_packed_object_sha1(p, first, now);
|
||||
const unsigned char *now, *next;
|
||||
now = nth_packed_object_sha1(p, first);
|
||||
if (match_sha(len, match, now)) {
|
||||
if (nth_packed_object_sha1(p, first+1, next) ||
|
||||
!match_sha(len, match, next)) {
|
||||
next = nth_packed_object_sha1(p, first+1);
|
||||
if (!next|| !match_sha(len, match, next)) {
|
||||
/* unique within this pack */
|
||||
if (!found) {
|
||||
hashcpy(found_sha1, now);
|
||||
found_sha1 = now;
|
||||
found++;
|
||||
}
|
||||
else if (hashcmp(found_sha1, now)) {
|
||||
|
||||
@@ -83,6 +83,15 @@ test_expect_failure \
|
||||
git-branch r &&
|
||||
git-branch -m q r/q'
|
||||
|
||||
mv .git/config .git/config-saved
|
||||
|
||||
test_expect_success 'git branch -m q Q without config should succeed' '
|
||||
git-branch -m q Q &&
|
||||
git-branch -m Q q
|
||||
'
|
||||
|
||||
mv .git/config-saved .git/config
|
||||
|
||||
git-config branch.s/s.dummy Hello
|
||||
|
||||
test_expect_success \
|
||||
|
||||
25
t/t4120-apply-popt.sh
Executable file
25
t/t4120-apply-popt.sh
Executable file
@@ -0,0 +1,25 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2007 Shawn O. Pearce
|
||||
#
|
||||
|
||||
test_description='git-apply -p handling.'
|
||||
|
||||
. ./test-lib.sh
|
||||
|
||||
test_expect_success setup '
|
||||
mkdir sub &&
|
||||
echo A >sub/file1 &&
|
||||
cp sub/file1 file1 &&
|
||||
git add sub/file1 &&
|
||||
echo B >sub/file1 &&
|
||||
git diff >patch.file &&
|
||||
rm sub/file1 &&
|
||||
rmdir sub
|
||||
'
|
||||
|
||||
test_expect_success 'apply git diff with -p2' '
|
||||
git apply -p2 patch.file
|
||||
'
|
||||
|
||||
test_done
|
||||
@@ -35,7 +35,8 @@ git commit -q -a -m first
|
||||
|
||||
git checkout -b second master
|
||||
git show first:a1 |
|
||||
sed -e 's/To die, t/To die! T/' -e 's/life;$/life./' > a1
|
||||
sed -e 's/To die, t/To die! T/' > a1
|
||||
echo "* END *" >>a1
|
||||
git commit -q -a -m second
|
||||
|
||||
# activate rerere
|
||||
@@ -50,10 +51,10 @@ test_expect_success 'recorded preimage' "grep ======= $rr/preimage"
|
||||
test_expect_success 'no postimage or thisimage yet' \
|
||||
"test ! -f $rr/postimage -a ! -f $rr/thisimage"
|
||||
|
||||
test_expect_success 'preimage have right number of lines' '
|
||||
test_expect_success 'preimage has right number of lines' '
|
||||
|
||||
cnt=$(sed -ne "/^<<<<<<</,/^>>>>>>>/p" $rr/preimage | wc -l) &&
|
||||
test "$cnt" = 10
|
||||
test $cnt = 9
|
||||
|
||||
'
|
||||
|
||||
@@ -75,10 +76,10 @@ cat > expect << EOF
|
||||
For in that sleep of death what dreams may come
|
||||
When we have shuffled off this mortal coil,
|
||||
Must give us pause: there's the respect
|
||||
-<<<<<<<
|
||||
-That makes calamity of so long life.
|
||||
-=======
|
||||
That makes calamity of so long life;
|
||||
-<<<<<<<
|
||||
-=======
|
||||
-* END *
|
||||
->>>>>>>
|
||||
EOF
|
||||
git rerere diff > out
|
||||
|
||||
@@ -137,4 +137,8 @@ test_expect_success \
|
||||
'validate file contents with prefix' \
|
||||
'diff -r a e/prefix/a'
|
||||
|
||||
test_expect_success \
|
||||
'git-archive --list outside of a git repo' \
|
||||
'GIT_DIR=some/non-existing/directory git-archive --list'
|
||||
|
||||
test_done
|
||||
|
||||
@@ -163,7 +163,7 @@ test_sequence()
|
||||
# the bisection point is the head - this is the bad point.
|
||||
#
|
||||
|
||||
test_output_expect_success "--bisect l5 ^root" 'git-rev-list $_bisect_option l5 ^root' <<EOF
|
||||
test_output_expect_success "$_bisect_option l5 ^root" 'git-rev-list $_bisect_option l5 ^root' <<EOF
|
||||
c3
|
||||
EOF
|
||||
|
||||
|
||||
@@ -7,7 +7,8 @@ test_description='git-rev-list trivial path optimization test'
|
||||
test_expect_success setup '
|
||||
echo Hello > a &&
|
||||
git add a &&
|
||||
git commit -m "Initial commit" a
|
||||
git commit -m "Initial commit" a &&
|
||||
initial=$(git rev-parse --verify HEAD)
|
||||
'
|
||||
|
||||
test_expect_success path-optimization '
|
||||
@@ -16,4 +17,35 @@ test_expect_success path-optimization '
|
||||
test $(git-rev-list $commit -- . | wc -l) = 1
|
||||
'
|
||||
|
||||
test_expect_success 'further setup' '
|
||||
git checkout -b side &&
|
||||
echo Irrelevant >c &&
|
||||
git add c &&
|
||||
git commit -m "Side makes an irrelevant commit" &&
|
||||
echo "More Irrelevancy" >c &&
|
||||
git add c &&
|
||||
git commit -m "Side makes another irrelevant commit" &&
|
||||
echo Bye >a &&
|
||||
git add a &&
|
||||
git commit -m "Side touches a" &&
|
||||
side=$(git rev-parse --verify HEAD) &&
|
||||
echo "Yet more Irrelevancy" >c &&
|
||||
git add c &&
|
||||
git commit -m "Side makes yet another irrelevant commit" &&
|
||||
git checkout master &&
|
||||
echo Another >b &&
|
||||
git add b &&
|
||||
git commit -m "Master touches b" &&
|
||||
git merge side &&
|
||||
echo Touched >b &&
|
||||
git add b &&
|
||||
git commit -m "Master touches b again"
|
||||
'
|
||||
|
||||
test_expect_success 'path optimization 2' '
|
||||
( echo "$side"; echo "$initial" ) >expected &&
|
||||
git rev-list HEAD -- a >actual &&
|
||||
diff -u expected actual
|
||||
'
|
||||
|
||||
test_done
|
||||
|
||||
@@ -260,7 +260,7 @@ static void wt_status_print_untracked(struct wt_status *s)
|
||||
if (file_exists(x))
|
||||
add_excludes_from_file(&dir, x);
|
||||
|
||||
read_directory(&dir, ".", "", 0);
|
||||
read_directory(&dir, ".", "", 0, NULL);
|
||||
for(i = 0; i < dir.nr; i++) {
|
||||
/* check for matching entry, which is unmerged; lifted from
|
||||
* builtin-ls-files:show_other_files */
|
||||
|
||||
Reference in New Issue
Block a user