Merge commit 'v1.6.0.2' into devel

Conflicts:
	t/t5530-upload-pack-error.sh
	t/t5602-clone-remote-exec.sh
	t/t7004-tag.sh
This commit is contained in:
Steffen Prohaska
2008-09-21 12:53:25 +02:00
180 changed files with 2096 additions and 1308 deletions

View File

@@ -0,0 +1,87 @@
GIT v1.6.0.2 Release Notes
==========================
Fixes since v1.6.0.1
--------------------
* Installation on platforms that needs .exe suffix to git-* programs were
broken in 1.6.0.1.
* Installation on filesystems without symbolic links support did nto
work well.
* In-tree documentations and test scripts now use "git foo" form to set a
better example, instead of the "git-foo" form (which is an acceptable
form if you have "PATH=$(git --exec-path):$PATH" in your script)
* Many commands did not use the correct working tree location when used
with GIT_WORK_TREE environment settings.
* Some systems needs to use compatibility fnmach and regex libraries
independent from each other; the compat/ area has been reorganized to
allow this.
* "git apply --unidiff-zero" incorrectly applied a -U0 patch that inserts
a new line before the second line.
* "git blame -c" did not exactly work like "git annotate" when range
boundaries are involved.
* "git checkout file" when file is still unmerged checked out contents from
a random high order stage, which was confusing.
* "git clone $there $here/" with extra trailing slashes after explicit
local directory name $here did not work as expected.
* "git diff" on tracked contents with CRLF line endings did not drive "less"
intelligently when showing added or removed lines.
* "git diff --dirstat -M" did not add changes in subdirectories up
correctly for renamed paths.
* "git diff --cumulative" did not imply "--dirstat".
* "git for-each-ref refs/heads/" did not work as expected.
* "git gui" allowed users to feed patch without any context to be applied.
* "git gui" botched parsing "diff" output when a line that begins with two
dashes and a space gets removed or a line that begins with two pluses
and a space gets added.
* "git gui" translation updates and i18n fixes.
* "git index-pack" is more careful against disk corruption while completing
a thin pack.
* "git log -i --grep=pattern" did not ignore case; neither "git log -E
--grep=pattern" triggered extended regexp.
* "git log --pretty="%ad" --date=short" did not use short format when
showing the timestamp.
* "git log --author=author" match incorrectly matched with the
timestamp part of "author " line in commit objects.
* "git log -F --author=author" did not work at all.
* Build procedure for "git shell" that used stub versions of some
functions and globals was not understood by linkers on some platforms.
* "git stash" was fooled by a stat-dirty but otherwise unmodified paths
and refused to work until the user refreshed the index.
* "git svn" was broken on Perl before 5.8 with recent fixes to reduce
use of temporary files.
* "git verify-pack -v" did not work correctly when given more than one
packfile.
Also contains many documentation updates.
--
exec >/var/tmp/1
O=v1.6.0.1-78-g3632cfc
echo O=$(git describe maint)
git shortlog --no-merges $O..maint

View File

@@ -693,7 +693,7 @@ gitcvs.logfile::
Path to a log file where the CVS server interface well... logs
various stuff. See linkgit:git-cvsserver[1].
gitcvs.usecrlfattr
gitcvs.usecrlfattr::
If true, the server will look up the `crlf` attribute for
files to determine the '-k' modes to use. If `crlf` is set,
the '-k' mode will be left blank, so cvs clients will

View File

@@ -59,12 +59,11 @@ endif::git-format-patch[]
lines.
--dirstat[=limit]::
Output only the sub-directories that are impacted by a diff,
and to what degree they are impacted. You can override the
default cut-off in percent (3) by "--dirstat=limit". If you
want to enable "cumulative" directory statistics, you can use
the "--cumulative" flag, which adds up percentages recursively
even when they have been already reported for a sub-directory.
Output the distribution of relative amount of changes (number of lines added or
removed) for each sub-directory. Directories with changes below
a cut-off percent (3% by default) are not shown. The cut-off percent
can be set with "--dirstat=limit". Changes in a child directory is not
counted for the parent directory, unless "--cumulative" is used.
--summary::
Output a condensed summary of extended header information

View File

@@ -14,6 +14,11 @@ DESCRIPTION
Annotates each line in the given file with information from the commit
which introduced the line. Optionally annotate from a given revision.
The only difference between this command and linkgit:git-blame[1] is that
they use slightly different output formats, and this command exists only
for backward compatibility to support existing scripts, and provide more
familiar command name for people coming from other SCM systems.
OPTIONS
-------
include::blame-options.txt[]

View File

@@ -79,9 +79,9 @@ Diagnostics
You don't exist. Go away!::
The passwd(5) gecos field couldn't be read
Your parents must have hated you!::
The password(5) gecos field is longer than a giant static buffer.
The passwd(5) gecos field is longer than a giant static buffer.
Your sysadmin must hate you!::
The password(5) name field is longer than a giant static buffer.
The passwd(5) name field is longer than a giant static buffer.
Discussion
----------

View File

@@ -16,7 +16,7 @@ DESCRIPTION
Iterate over all refs that match `<pattern>` and show them
according to the given `<format>`, after sorting them according
to the given set of `<key>`. If `<max>` is given, stop after
to the given set of `<key>`. If `<count>` is given, stop after
showing that many refs. The interpolated values in `<format>`
can optionally be quoted as string literals in the specified
host language allowing their direct evaluation in that language.

View File

@@ -59,7 +59,7 @@ Enter 'git-name-rev':
------------
% git name-rev 33db5f4d9027a10e477ccf054b2c1ab94f74c85a
33db5f4d9027a10e477ccf054b2c1ab94f74c85a tags/v0.99^0~940
33db5f4d9027a10e477ccf054b2c1ab94f74c85a tags/v0.99~940
------------
Now you are wiser, because you know that it happened 940 revisions before v0.99.

View File

@@ -179,6 +179,9 @@ user is prompted for a password while the input is masked for privacy.
This is useful if your default address is not the address that is
subscribed to a list. If you use the sendmail binary, you must have
suitable privileges for the -f parameter.
Default is the value of the 'sendemail.envelopesender' configuration
variable; if that is unspecified, choosing the envelope sender is left
to your MTA.
--to::
Specify the primary recipient of the emails generated.

View File

@@ -159,7 +159,7 @@ perform a pull, and then unstash, like this:
+
----------------------------------------------------------------
$ git pull
...
...
file foobar not up to date, cannot merge.
$ git stash
$ git pull
@@ -174,7 +174,7 @@ make a commit to a temporary branch to store your changes away, and
return to your original branch to make the emergency fix, like this:
+
----------------------------------------------------------------
... hack hack hack ...
# ... hack hack hack ...
$ git checkout -b my_wip
$ git commit -a -m "WIP"
$ git checkout master
@@ -182,18 +182,18 @@ $ edit emergency fix
$ git commit -a -m "Fix in a hurry"
$ git checkout my_wip
$ git reset --soft HEAD^
... continue hacking ...
# ... continue hacking ...
----------------------------------------------------------------
+
You can use 'git-stash' to simplify the above, like this:
+
----------------------------------------------------------------
... hack hack hack ...
# ... hack hack hack ...
$ git stash
$ edit emergency fix
$ git commit -a -m "Fix in a hurry"
$ git stash apply
... continue hacking ...
# ... continue hacking ...
----------------------------------------------------------------
Testing partial commits::
@@ -203,13 +203,13 @@ more commits out of the changes in the work tree, and you want to test
each change before committing:
+
----------------------------------------------------------------
... hack hack hack ...
# ... hack hack hack ...
$ git add --patch foo # add just first part to the index
$ git stash save --keep-index # save all other changes to the stash
$ edit/build/test first part
$ git commit foo -m 'First part' # commit fully tested change
$ git commit -m 'First part' # commit fully tested change
$ git stash pop # prepare to work on all other changes
... repeat above five steps until one commit remains ...
# ... repeat above five steps until one commit remains ...
$ edit/build/test remaining parts
$ git commit foo -m 'Remaining parts'
----------------------------------------------------------------

View File

@@ -20,7 +20,7 @@ OPTIONS
Cause the logical variables to be listed. In addition, all the
variables of the git configuration file .git/config are listed
as well. (However, the configuration variables listing functionality
is deprecated in favor of 'git-config -l'.)
is deprecated in favor of 'git config -l'.)
EXAMPLE
--------
@@ -41,9 +41,9 @@ Diagnostics
You don't exist. Go away!::
The passwd(5) gecos field couldn't be read
Your parents must have hated you!::
The password(5) gecos field is longer than a giant static buffer.
The passwd(5) gecos field is longer than a giant static buffer.
Your sysadmin must hate you!::
The password(5) name field is longer than a giant static buffer.
The passwd(5) name field is longer than a giant static buffer.
SEE ALSO
--------

View File

@@ -77,7 +77,7 @@ the URLs passed as arguments.
Note about konqueror
--------------------
When 'konqueror' is specified by the a command line option or a
When 'konqueror' is specified by a command line option or a
configuration variable, we launch 'kfmclient' to try to open the HTML
man page on an already opened konqueror in a new tab if possible.

View File

@@ -43,9 +43,11 @@ unreleased) version of git, that is available from 'master'
branch of the `git.git` repository.
Documentation for older releases are available here:
* link:v1.6.0/git.html[documentation for release 1.6.0]
* link:v1.6.0.2/git.html[documentation for release 1.6.0.2]
* release notes for
link:RelNotes-1.6.0.2.txt[1.6.0.2],
link:RelNotes-1.6.0.1.txt[1.6.0.1],
link:RelNotes-1.6.0.txt[1.6.0].
* link:v1.5.6.5/git.html[documentation for release 1.5.6.5]

View File

@@ -7,7 +7,7 @@ gitattributes - defining attributes per path
SYNOPSIS
--------
$GIT_DIR/info/attributes, gitattributes
$GIT_DIR/info/attributes, .gitattributes
DESCRIPTION
@@ -105,9 +105,8 @@ Set::
Unset::
Unsetting the `crlf` attribute on a path is meant to
mark the path as a "binary" file. The path never goes
through line endings conversion upon checkin/checkout.
Unsetting the `crlf` attribute on a path tells git not to
attempt any end-of-line conversion upon checkin or checkout.
Unspecified::
@@ -312,7 +311,7 @@ patterns are available:
- `bibtex` suitable for files with BibTeX coded references.
- `java` suitable for source code in the Java lanugage.
- `java` suitable for source code in the Java language.
- `pascal` suitable for source code in the Pascal/Delphi language.
@@ -482,6 +481,41 @@ in the file. E.g. the string `$Format:%H$` will be replaced by the
commit hash.
USING ATTRIBUTE MACROS
----------------------
You do not want any end-of-line conversions applied to, nor textual diffs
produced for, any binary file you track. You would need to specify e.g.
------------
*.jpg -crlf -diff
------------
but that may become cumbersome, when you have many attributes. Using
attribute macros, you can specify groups of attributes set or unset at
the same time. The system knows a built-in attribute macro, `binary`:
------------
*.jpg binary
------------
which is equivalent to the above. Note that the attribute macros can only
be "Set" (see the above example that sets "binary" macro as if it were an
ordinary attribute --- setting it in turn unsets "crlf" and "diff").
DEFINING ATTRIBUTE MACROS
-------------------------
Custom attribute macros can be defined only in the `.gitattributes` file
at the toplevel (i.e. not in any subdirectory). The built-in attribute
macro "binary" is equivalent to:
------------
[attr]binary -diff -crlf
------------
EXAMPLE
-------

View File

@@ -49,6 +49,13 @@ frequently used options.
the history between two branches (i.e. the HEAD and the MERGE_HEAD)
that modify the conflicted files.
--argscmd=<command>::
Command to be run each time gitk has to determine the list of
<revs> to show. The command is expected to print on its standard
output a list of additional revs to be shown, one per line.
Use this instead of explicitly specifying <revs> if the set of
commits to show may vary between refreshes.
<revs>::
Limit the revisions to show. This can be either a single revision

View File

@@ -7,7 +7,7 @@ gitmodules - defining submodule properties
SYNOPSIS
--------
gitmodules
$GIT_WORK_DIR/.gitmodules
DESCRIPTION

View File

@@ -321,10 +321,37 @@ pulling, like this:
------------------------------------------------
alice$ git fetch /home/bob/myrepo master
alice$ git log -p ..FETCH_HEAD
alice$ git log -p HEAD..FETCH_HEAD
------------------------------------------------
This operation is safe even if Alice has uncommitted local changes.
The range notation HEAD..FETCH_HEAD" means "show everything that is reachable
from the FETCH_HEAD but exclude anything that is reachable from HEAD.
Alice already knows everything that leads to her current state (HEAD),
and reviewing what Bob has in his state (FETCH_HEAD) that she has not
seen with this command
If Alice wants to visualize what Bob did since their histories forked
she can issue the following command:
------------------------------------------------
$ gitk HEAD..FETCH_HEAD
------------------------------------------------
This uses the same two-dot range notation we saw earlier with 'git log'.
Alice may want to view what both of them did since they forked.
She can use three-dot form instead of the two-dot form:
------------------------------------------------
$ gitk HEAD...FETCH_HEAD
------------------------------------------------
This means "show everything that is reachable from either one, but
exclude anything that is reachable from both of them".
Please note that these range notation can be used with both gitk
and "git log".
After inspecting what Bob did, if there is nothing urgent, Alice may
decide to continue working without pulling from Bob. If Bob's history

View File

@@ -21,7 +21,7 @@ project find it more convenient to use legacy encodings, git
does not forbid it. However, there are a few things to keep in
mind.
. 'git-commit-tree' (hence, 'git-commit' which uses it) issues
. 'git-commit' and 'git-commit-tree' issues
a warning if the commit log message given to it does not look
like a valid UTF-8 string, unless you explicitly say your
project uses a legacy encoding. The way to say this is to

View File

@@ -1,5 +1,5 @@
merge.stat::
Whether to print the diffstat between ORIG_HEAD and merge result
Whether to print the diffstat between ORIG_HEAD and the merge result
at the end of the merge. True by default.
merge.log::

View File

@@ -103,7 +103,7 @@ The placeholders are:
- '%an': author name
- '%aN': author name (respecting .mailmap)
- '%ae': author email
- '%ad': author date
- '%ad': author date (format respects --date= option)
- '%aD': author date, RFC2822 style
- '%ar': author date, relative
- '%at': author date, UNIX timestamp

View File

@@ -1,7 +1,7 @@
#!/bin/sh
GVF=GIT-VERSION-FILE
DEF_VER=v1.6.0.GIT
DEF_VER=v1.6.0.2.GIT
LF='
'

View File

@@ -333,7 +333,6 @@ endif
export PERL_PATH
LIB_FILE=libgit.a
COMPAT_LIB = compat/lib.a
XDIFF_LIB=xdiff/lib.a
LIB_H += archive.h
@@ -359,6 +358,7 @@ LIB_H += list-objects.h
LIB_H += ll-merge.h
LIB_H += log-tree.h
LIB_H += mailmap.h
LIB_H += merge-recursive.h
LIB_H += object.h
LIB_H += pack.h
LIB_H += pack-refs.h
@@ -626,6 +626,8 @@ ifeq ($(uname_S),Darwin)
endif
NO_STRLCPY = YesPlease
NO_MEMMEM = YesPlease
COMPAT_CFLAGS += -Icompat/regex
COMPAT_OBJS += compat/regex/regex.o
endif
ifeq ($(uname_S),SunOS)
NEEDS_SOCKET = YesPlease
@@ -675,6 +677,8 @@ ifeq ($(uname_S),FreeBSD)
BASIC_CFLAGS += -I/usr/local/include
BASIC_LDFLAGS += -L/usr/local/lib
DIR_HAS_BSD_GROUP_SEMANTICS = YesPlease
COMPAT_CFLAGS += -Icompat/regex
COMPAT_OBJS += compat/regex/regex.o
endif
ifeq ($(uname_S),OpenBSD)
NO_STRCASESTR = YesPlease
@@ -700,6 +704,8 @@ ifeq ($(uname_S),AIX)
INTERNAL_QSORT = UnfortunatelyYes
NEEDS_LIBICONV=YesPlease
BASIC_CFLAGS += -D_LARGE_FILES
COMPAT_CFLAGS += -Icompat/regex
COMPAT_OBJS += compat/regex/regex.o
endif
ifeq ($(uname_S),GNU)
# GNU/Hurd
@@ -751,10 +757,10 @@ ifneq (,$(findstring MINGW,$(uname_S)))
NO_R_TO_GCC_LINKER = YesPlease
INTERNAL_QSORT = YesPlease
NO_POSIX_ONLY_PROGRAMS = YesPlease
COMPAT_CFLAGS += -D__USE_MINGW_ACCESS -DNOGDI -Icompat
COMPAT_CFLAGS += -D__USE_MINGW_ACCESS -DNOGDI -Icompat -Icompat/regex -Icompat/fnmatch
COMPAT_CFLAGS += -DSNPRINTF_SIZE_CORR=1
COMPAT_CFLAGS += -DSTRIP_EXTENSION=\".exe\"
COMPAT_OBJS += compat/mingw.o compat/fnmatch.o compat/regex.o compat/winansi.o
COMPAT_OBJS += compat/mingw.o compat/fnmatch/fnmatch.o compat/regex/regex.o compat/winansi.o
EXTLIBS += -lws2_32
X = .exe
NOEXECTEMPL = .noexec
@@ -1103,7 +1109,10 @@ help.o: help.c common-cmds.h GIT-CFLAGS
'-DGIT_INFO_PATH="$(infodir_SQ)"' $<
$(BUILT_INS): git$X
$(QUIET_BUILT_IN)$(RM) $@ && ln git$X $@
$(QUIET_BUILT_IN)$(RM) $@ && \
ln git$X $@ 2>/dev/null || \
ln -s git$X $@ 2>/dev/null || \
cp git$X $@
common-cmds.h: ./generate-cmdlist.sh command-list.txt
@@ -1229,12 +1238,6 @@ git-http-push$X: revision.o http.o http-push.o $(GITLIBS)
$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \
$(LIBS) $(CURL_LIBCURL) $(EXPAT_LIBEXPAT)
$(COMPAT_LIB): $(COMPAT_OBJS)
$(QUIET_AR)$(RM) $@ && $(AR) rcs $@ $(COMPAT_OBJS)
git-shell$X: abspath.o ctype.o exec_cmd.o quote.o strbuf.o usage.o wrapper.o shell.o $(COMPAT_LIB)
$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(COMPAT_LIB)
$(LIB_OBJS) $(BUILTIN_OBJS): $(LIB_H)
$(patsubst git-%$X,%.o,$(PROGRAMS)): $(LIB_H) $(wildcard */*.h)
builtin-revert.o wt-status.o: wt-status.h
@@ -1369,16 +1372,13 @@ ifneq (,$X)
endif
bindir=$$(cd '$(DESTDIR_SQ)$(bindir_SQ)' && pwd) && \
execdir=$$(cd '$(DESTDIR_SQ)$(gitexec_instdir_SQ)' && pwd) && \
if test "z$$bindir" != "z$$execdir"; \
then \
ln -f "$$bindir/git$X" "$$execdir/git$X" || \
cp "$$bindir/git$X" "$$execdir/git$X"; \
fi && \
{ $(foreach p,$(BUILT_INS), $(RM) "$$execdir/$p" && ln "$$execdir/git$X" "$$execdir/$p" ;) } && \
if test "z$$bindir" != "z$$execdir"; \
then \
$(RM) "$$execdir/git$X"; \
fi && \
{ $(RM) "$$execdir/git-add$X" && \
ln git-add$X "$$execdir/git-add$X" 2>/dev/null || \
cp git-add$X "$$execdir/git-add$X"; } && \
{ $(foreach p,$(filter-out git-add$X,$(BUILT_INS)), $(RM) "$$execdir/$p" && \
ln "$$execdir/git-add$X" "$$execdir/$p" 2>/dev/null || \
ln -s "git-add$X" "$$execdir/$p" 2>/dev/null || \
cp "$$execdir/git-add$X" "$$execdir/$p" || exit;) } && \
./check_bindir "z$$bindir" "z$$execdir" "$$bindir/git-add$X"
install-doc:
@@ -1447,7 +1447,7 @@ distclean: clean
clean:
$(RM) *.o mozilla-sha1/*.o arm/*.o ppc/*.o compat/*.o xdiff/*.o \
$(LIB_FILE) $(XDIFF_LIB) $(COMPAT_LIB)
$(LIB_FILE) $(XDIFF_LIB)
$(RM) $(ALL_PROGRAMS) $(BUILT_INS) git$X
$(RM) $(TEST_PROGRAMS)
$(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo common-cmds.h TAGS tags cscope*

View File

@@ -1 +1 @@
Documentation/RelNotes-1.6.0.1.txt
Documentation/RelNotes-1.6.0.2.txt

View File

@@ -48,7 +48,7 @@ static void format_subst(const struct commit *commit,
strbuf_add(&fmt, b + 8, c - b - 8);
strbuf_add(buf, src, b - src);
format_commit_message(commit, fmt.buf, buf);
format_commit_message(commit, fmt.buf, buf, DATE_NORMAL);
len -= c + 1 - src;
src = c + 1;
}

View File

@@ -274,7 +274,7 @@ static void say_patch_name(FILE *output, const char *pre,
static void read_patch_file(struct strbuf *sb, int fd)
{
if (strbuf_read(sb, fd, 0) < 0)
die("git-apply: read returned %s", strerror(errno));
die("git apply: read returned %s", strerror(errno));
/*
* Make sure that we have some slop in the buffer
@@ -506,17 +506,17 @@ static char *gitdiff_verify_name(const char *line, int isnull, char *orig_name,
name = orig_name;
len = strlen(name);
if (isnull)
die("git-apply: bad git-diff - expected /dev/null, got %s on line %d", name, linenr);
die("git apply: bad git-diff - expected /dev/null, got %s on line %d", name, linenr);
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);
die("git apply: bad git-diff - inconsistent %s filename on line %d", oldnew, linenr);
free(another);
return orig_name;
}
else {
/* expect "/dev/null" */
if (memcmp("/dev/null", line, 9) || line[9] != '\n')
die("git-apply: bad git-diff - expected /dev/null on line %d", linenr);
die("git apply: bad git-diff - expected /dev/null on line %d", linenr);
return NULL;
}
}
@@ -1996,6 +1996,8 @@ static int apply_one_fragment(struct image *img, struct fragment *frag,
/*
* A hunk to change lines at the beginning would begin with
* @@ -1,L +N,M @@
* but we need to be careful. -U0 that inserts before the second
* line also has this pattern.
*
* And a hunk to add to an empty file would begin with
* @@ -0,0 +N,M @@
@@ -2003,7 +2005,8 @@ static int apply_one_fragment(struct image *img, struct fragment *frag,
* In other words, a hunk that is (frag->oldpos <= 1) with or
* without leading context must match at the beginning.
*/
match_beginning = frag->oldpos <= 1;
match_beginning = (!frag->oldpos ||
(frag->oldpos == 1 && !unidiff_zero));
/*
* A hunk without trailing lines must match at the end.

View File

@@ -47,18 +47,18 @@ static int run_remote_archiver(const char *remote, int argc,
len = packet_read_line(fd[0], buf, sizeof(buf));
if (!len)
die("git-archive: expected ACK/NAK, got EOF");
die("git archive: expected ACK/NAK, got EOF");
if (buf[len-1] == '\n')
buf[--len] = 0;
if (strcmp(buf, "ACK")) {
if (len > 5 && !prefixcmp(buf, "NACK "))
die("git-archive: NACK %s", buf + 5);
die("git-archive: protocol error");
die("git archive: NACK %s", buf + 5);
die("git archive: protocol error");
}
len = packet_read_line(fd[0], buf, sizeof(buf));
if (len)
die("git-archive: expected a flush");
die("git archive: expected a flush");
/* Now, start reading from fd[0] and spit it out to stdout */
rv = recv_sideband("archive", fd[0], 1, 2);

View File

@@ -38,7 +38,6 @@ static int show_root;
static int reverse;
static int blank_boundary;
static int incremental;
static int cmd_is_annotate;
static int xdl_opts = XDF_NEED_MINIMAL;
static struct string_list mailmap;
@@ -1686,7 +1685,7 @@ static void emit_other(struct scoreboard *sb, struct blame_entry *ent, int opt)
if (suspect->commit->object.flags & UNINTERESTING) {
if (blank_boundary)
memset(hex, ' ', length);
else if (!cmd_is_annotate) {
else if (!(opt & OUTPUT_ANNOTATE_COMPAT)) {
length--;
putchar('^');
}
@@ -1791,7 +1790,7 @@ static int prepare_lines(struct scoreboard *sb)
/*
* Add phony grafts for use with -S; this is primarily to
* support git-cvsserver that wants to give a linear history
* support git's cvsserver that wants to give a linear history
* to its clients.
*/
static int read_ancestry(const char *graft_file)
@@ -2317,8 +2316,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
};
struct parse_opt_ctx_t ctx;
cmd_is_annotate = !strcmp(argv[0], "annotate");
int cmd_is_annotate = !strcmp(argv[0], "annotate");
git_config(git_blame_config, NULL);
init_revisions(&revs, NULL);
@@ -2346,6 +2344,9 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
parse_done:
argc = parse_options_end(&ctx);
if (cmd_is_annotate)
output_option |= OUTPUT_ANNOTATE_COMPAT;
if (DIFF_OPT_TST(&revs.diffopt, FIND_COPIES_HARDER))
opt |= (PICKAXE_BLAME_COPY | PICKAXE_BLAME_MOVE |
PICKAXE_BLAME_COPY_HARDER);

View File

@@ -6,10 +6,10 @@
* Basic handler for bundle files to connect repositories via sneakernet.
* Invocation must include action.
* This function can create a bundle or provide information on an existing
* bundle supporting git-fetch, git-pull, and git-ls-remote
* bundle supporting "fetch", "pull", and "ls-remote".
*/
static const char *bundle_usage="git-bundle (create <bundle> <git-rev-list args> | verify <bundle> | list-heads <bundle> [refname]... | unbundle <bundle> [refname]... )";
static const char *bundle_usage="git bundle (create <bundle> <git rev-list args> | verify <bundle> | list-heads <bundle> [refname]... | unbundle <bundle> [refname]... )";
int cmd_bundle(int argc, const char **argv, const char *prefix)
{

View File

@@ -137,11 +137,11 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name)
break;
default:
die("git-cat-file: unknown option: %s\n", exp_type);
die("git cat-file: unknown option: %s\n", exp_type);
}
if (!buf)
die("git-cat-file %s: bad file", obj_name);
die("git cat-file %s: bad file", obj_name);
write_or_die(1, buf, size);
return 0;

View File

@@ -9,6 +9,6 @@
int cmd_check_ref_format(int argc, const char **argv, const char *prefix)
{
if (argc != 2)
usage("git-check-ref-format refname");
usage("git check-ref-format refname");
return !!check_ref_format(argv[1]);
}

View File

@@ -5,26 +5,26 @@
*
* Careful: order of argument flags does matter. For example,
*
* git-checkout-index -a -f file.c
* git checkout-index -a -f file.c
*
* Will first check out all files listed in the cache (but not
* overwrite any old ones), and then force-checkout "file.c" a
* second time (ie that one _will_ overwrite any old contents
* with the same filename).
*
* Also, just doing "git-checkout-index" does nothing. You probably
* meant "git-checkout-index -a". And if you want to force it, you
* want "git-checkout-index -f -a".
* Also, just doing "git checkout-index" does nothing. You probably
* meant "git checkout-index -a". And if you want to force it, you
* want "git checkout-index -f -a".
*
* Intuitiveness is not the goal here. Repeatability is. The
* reason for the "no arguments means no work" thing is that
* from scripts you are supposed to be able to do things like
*
* find . -name '*.h' -print0 | xargs -0 git-checkout-index -f --
* find . -name '*.h' -print0 | xargs -0 git checkout-index -f --
*
* or:
*
* find . -name '*.h' -print0 | git-checkout-index -f -z --stdin
* find . -name '*.h' -print0 | git checkout-index -f -z --stdin
*
* which will force all existing *.h files to be replaced with
* their cached copies. If an empty command line implied "all",
@@ -107,7 +107,7 @@ static int checkout_file(const char *name, int prefix_length)
}
if (!state.quiet) {
fprintf(stderr, "git-checkout-index: %s ", name);
fprintf(stderr, "git checkout-index: %s ", name);
if (!has_same_name)
fprintf(stderr, "is not in the cache");
else if (checkout_stage)
@@ -258,9 +258,9 @@ int cmd_checkout_index(int argc, const char **argv, const char *prefix)
const char *p;
if (all)
die("git-checkout-index: don't mix '--all' and explicit filenames");
die("git checkout-index: don't mix '--all' and explicit filenames");
if (read_from_stdin)
die("git-checkout-index: don't mix '--stdin' and explicit filenames");
die("git checkout-index: don't mix '--stdin' and explicit filenames");
p = prefix_path(prefix, prefix_length, arg);
checkout_file(p, prefix_length);
if (p < arg || p > arg + strlen(arg))
@@ -271,7 +271,7 @@ int cmd_checkout_index(int argc, const char **argv, const char *prefix)
struct strbuf buf, nbuf;
if (all)
die("git-checkout-index: don't mix '--all' and '--stdin'");
die("git checkout-index: don't mix '--all' and '--stdin'");
strbuf_init(&buf, 0);
strbuf_init(&nbuf, 0);

View File

@@ -76,6 +76,15 @@ static int read_tree_some(struct tree *tree, const char **pathspec)
return 0;
}
static int skip_same_name(struct cache_entry *ce, int pos)
{
while (++pos < active_nr &&
!strcmp(active_cache[pos]->name, ce->name))
; /* skip */
return pos;
}
static int checkout_paths(struct tree *source_tree, const char **pathspec)
{
int pos;
@@ -107,6 +116,20 @@ static int checkout_paths(struct tree *source_tree, const char **pathspec)
if (report_path_error(ps_matched, pathspec, 0))
return 1;
/* Any unmerged paths? */
for (pos = 0; pos < active_nr; pos++) {
struct cache_entry *ce = active_cache[pos];
if (pathspec_match(pathspec, NULL, ce->name, 0)) {
if (!ce_stage(ce))
continue;
errs = 1;
error("path '%s' is unmerged", ce->name);
pos = skip_same_name(ce, pos) - 1;
}
}
if (errs)
return 1;
/* Now we are committed to check them out */
memset(&state, 0, sizeof(state));
state.force = 1;
@@ -114,7 +137,11 @@ static int checkout_paths(struct tree *source_tree, const char **pathspec)
for (pos = 0; pos < active_nr; pos++) {
struct cache_entry *ce = active_cache[pos];
if (pathspec_match(pathspec, NULL, ce->name, 0)) {
errs |= checkout_entry(ce, &state, NULL);
if (!ce_stage(ce)) {
errs |= checkout_entry(ce, &state, NULL);
continue;
}
pos = skip_same_name(ce, pos) - 1;
}
}
@@ -386,13 +413,11 @@ static int switch_branches(struct checkout_opts *opts, struct branch_info *new)
}
/*
* If the new thing isn't a branch and isn't HEAD and we're
* not starting a new branch, and we want messages, and we
* weren't on a branch, and we're moving to a new commit,
* describe the old commit.
* If we were on a detached HEAD, but we are now moving to
* a new commit, we want to mention the old commit once more
* to remind the user that it might be lost.
*/
if (!new->path && strcmp(new->name, "HEAD") && !opts->new_branch &&
!opts->quiet && !old.path && new->commit != old.commit)
if (!opts->quiet && !old.path && new->commit != old.commit)
describe_detached_head("Previous HEAD position was", old.commit);
if (!old.commit) {

View File

@@ -147,6 +147,15 @@ static int is_directory(const char *path)
return !stat(path, &buf) && S_ISDIR(buf.st_mode);
}
static void strip_trailing_slashes(char *dir)
{
char *end = dir + strlen(dir);
while (dir < end - 1 && is_dir_sep(end[-1]))
end--;
*end = '\0';
}
static void setup_reference(const char *repo)
{
const char *ref_git;
@@ -387,7 +396,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
path = get_repo_path(repo_name, &is_bundle);
if (path)
repo = path;
repo = xstrdup(make_nonrelative_path(repo_name));
else if (!strchr(repo_name, ':'))
repo = xstrdup(make_absolute_path(repo_name));
else
@@ -397,6 +406,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
dir = xstrdup(argv[1]);
else
dir = guess_dir_name(repo_name, is_bundle, option_bare);
strip_trailing_slashes(dir);
if (!stat(dir, &buf))
die("destination directory '%s' already exists.", dir);
@@ -422,10 +432,11 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
if (!option_bare) {
junk_work_tree = work_tree;
if (safe_create_leading_directories_const(work_tree) < 0)
die("could not create leading directories of '%s'",
work_tree);
die("could not create leading directories of '%s': %s",
work_tree, strerror(errno));
if (mkdir(work_tree, 0755))
die("could not create work tree dir '%s'.", work_tree);
die("could not create work tree dir '%s': %s.",
work_tree, strerror(errno));
set_git_work_tree(work_tree);
}
junk_git_dir = git_dir;

View File

@@ -24,7 +24,7 @@ static void check_valid(unsigned char *sha1, enum object_type expect)
typename(expect));
}
static const char commit_tree_usage[] = "git-commit-tree <sha1> [-p <sha1>]* < changelog";
static const char commit_tree_usage[] = "git commit-tree <sha1> [-p <sha1>]* < changelog";
static void new_parent(struct commit *parent, struct commit_list **parents_p)
{
@@ -118,7 +118,7 @@ int cmd_commit_tree(int argc, const char **argv, const char *prefix)
}
if (strbuf_read(&buffer, 0, 0) < 0)
die("git-commit-tree: read returned %s", strerror(errno));
die("git commit-tree: read returned %s", strerror(errno));
if (!commit_tree(buffer.buf, tree_sha1, parents, commit_sha1)) {
printf("%s\n", sha1_to_hex(commit_sha1));

View File

@@ -882,7 +882,7 @@ static void print_summary(const char *prefix, const unsigned char *sha1)
if (!log_tree_commit(&rev, commit)) {
struct strbuf buf = STRBUF_INIT;
format_commit_message(commit, "%h: %s", &buf);
format_commit_message(commit, "%h: %s", &buf, DATE_NORMAL);
printf("%s\n", buf.buf);
strbuf_release(&buf);
}

View File

@@ -39,6 +39,8 @@ int cmd_diff_index(int argc, const char **argv, const char *prefix)
if (rev.pending.nr != 1 ||
rev.max_count != -1 || rev.min_age != -1 || rev.max_age != -1)
usage(diff_cache_usage);
if (!cached)
setup_work_tree();
if (read_cache() < 0) {
perror("read_cache");
return -1;

View File

@@ -122,6 +122,8 @@ static int builtin_diff_index(struct rev_info *revs,
usage(builtin_diff_usage);
argv++; argc--;
}
if (!cached)
setup_work_tree();
/*
* Make sure there is one revision (i.e. pending object),
* and there is no revision filtering parameters.
@@ -225,6 +227,7 @@ static int builtin_diff_files(struct rev_info *revs, int argc, const char **argv
(revs->diffopt.output_format & DIFF_FORMAT_PATCH))
revs->combine_merges = revs->dense_combined_merges = 1;
setup_work_tree();
if (read_cache() < 0) {
perror("read_cache");
return -1;

View File

@@ -417,7 +417,8 @@ static void export_marks(char *file)
for (i = 0; i < idnums.size; i++) {
if (deco->base && deco->base->type == 1) {
mark = ptr_to_mark(deco->decoration);
fprintf(f, ":%u %s\n", mark, sha1_to_hex(deco->base->sha1));
fprintf(f, ":%"PRIu32" %s\n", mark,
sha1_to_hex(deco->base->sha1));
}
deco++;
}

View File

@@ -609,7 +609,7 @@ static struct ref *do_fetch_pack(int fd[2],
fprintf(stderr, "warning: no common commits\n");
if (get_pack(fd, pack_lockfile))
die("git-fetch-pack: fetch failed.");
die("git fetch-pack: fetch failed.");
all_done:
return ref;
@@ -750,7 +750,7 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix)
if (!ret && nr_heads) {
/* If the heads to pull were given, we should have
* consumed all of them by matching the remote.
* Otherwise, 'git-fetch remote no-such-ref' would
* Otherwise, 'git fetch remote no-such-ref' would
* silently succeed without issuing an error.
*/
for (i = 0; i < nr_heads; i++)

View File

@@ -86,10 +86,10 @@ static void add_merge_config(struct ref **head,
/*
* Not fetched to a tracking branch? We need to fetch
* it anyway to allow this branch's "branch.$name.merge"
* to be honored by git-pull, but we do not have to
* to be honored by 'git pull', but we do not have to
* fail if branch.$name.merge is misconfigured to point
* at a nonexisting branch. If we were indeed called by
* git-pull, it will notice the misconfiguration because
* 'git pull', it will notice the misconfiguration because
* there is no entry in the resulting FETCH_HEAD marked
* for merging.
*/
@@ -396,7 +396,7 @@ static int store_updated_refs(const char *url, const char *remote_name,
* The refs we are going to fetch are in to_fetch (nr_heads in
* total). If running
*
* $ git-rev-list --objects to_fetch[0] to_fetch[1] ... --not --all
* $ git rev-list --objects to_fetch[0] to_fetch[1] ... --not --all
*
* does not error out, that means everything reachable from the
* refs we are going to fetch exists and is connected to some of

View File

@@ -652,7 +652,8 @@ static int grab_single_ref(const char *refname, const unsigned char *sha1, int f
if ((plen <= namelen) &&
!strncmp(refname, p, plen) &&
(refname[plen] == '\0' ||
refname[plen] == '/'))
refname[plen] == '/' ||
p[plen-1] == '/'))
break;
if (!fnmatch(p, refname, FNM_PATHNAME))
break;

View File

@@ -774,7 +774,7 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
/* Make sure we do not get outside of paths */
for (i = 0; paths[i]; i++)
if (strncmp(prefix, paths[i], opt.prefix_length))
die("git-grep: cannot generate relative filenames containing '..'");
die("git grep: cannot generate relative filenames containing '..'");
}
}
else if (prefix) {
@@ -783,8 +783,11 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
paths[1] = NULL;
}
if (!list.nr)
if (!list.nr) {
if (!cached)
setup_work_tree();
return !grep_cache(&opt, paths, cached);
}
if (cached)
die("both --cached and trees are given.");

View File

@@ -42,7 +42,7 @@ int cmd_http_fetch(int argc, const char **argv, const char *prefix)
arg++;
}
if (argc < arg + 2 - commits_on_stdin) {
usage("git-http-fetch [-c] [-t] [-a] [-v] [--recover] [-w ref] [--stdin] commit-id url");
usage("git http-fetch [-c] [-t] [-a] [-v] [--recover] [-w ref] [--stdin] commit-id url");
return 1;
}
if (commits_on_stdin) {
@@ -75,7 +75,7 @@ int cmd_http_fetch(int argc, const char **argv, const char *prefix)
fprintf(stderr,
"Some loose object were found to be corrupt, but they might be just\n"
"a false '404 Not Found' error message sent with incorrect HTTP\n"
"status code. Suggest running git-fsck.\n");
"status code. Suggest running 'git fsck'.\n");
}
walker_free(walker);

View File

@@ -78,7 +78,7 @@ static void show_dir_entry(const char *tag, struct dir_entry *ent)
int offset = prefix_offset;
if (len >= ent->len)
die("git-ls-files: internal error - directory entry not superset of prefix");
die("git ls-files: internal error - directory entry not superset of prefix");
if (pathspec && !pathspec_match(pathspec, ps_matched, ent->name, len))
return;
@@ -183,7 +183,7 @@ static void show_ce_entry(const char *tag, struct cache_entry *ce)
int offset = prefix_offset;
if (len >= ce_namelen(ce))
die("git-ls-files: internal error - cache entry not superset of prefix");
die("git ls-files: internal error - cache entry not superset of prefix");
if (pathspec && !pathspec_match(pathspec, ps_matched, ce->name, len))
return;
@@ -319,7 +319,7 @@ static const char *verify_pathspec(const char *prefix)
}
if (prefix_offset > max || memcmp(prev, prefix, prefix_offset))
die("git-ls-files: cannot generate relative filenames containing '..'");
die("git ls-files: cannot generate relative filenames containing '..'");
prefix_len = max;
return max ? xmemdupz(prev, max) : NULL;

View File

@@ -410,25 +410,22 @@ static unsigned long write_object(struct sha1file *f,
return hdrlen + datalen;
}
static off_t write_one(struct sha1file *f,
static int write_one(struct sha1file *f,
struct object_entry *e,
off_t offset)
off_t *offset)
{
unsigned long size;
/* offset is non zero if object is written already. */
if (e->idx.offset || e->preferred_base)
return offset;
return 1;
/* if we are deltified, write out base object first. */
if (e->delta) {
offset = write_one(f, e->delta, offset);
if (!offset)
return 0;
}
if (e->delta && !write_one(f, e->delta, offset))
return 0;
e->idx.offset = offset;
size = write_object(f, e, offset);
e->idx.offset = *offset;
size = write_object(f, e, *offset);
if (!size) {
e->idx.offset = 0;
return 0;
@@ -436,9 +433,10 @@ static off_t write_one(struct sha1file *f,
written_list[nr_written++] = &e->idx;
/* make sure off_t is sufficiently large not to wrap */
if (offset > offset + size)
if (*offset > *offset + size)
die("pack too large for current definition of off_t");
return offset + size;
*offset += size;
return 1;
}
/* forward declaration for write_pack_file */
@@ -448,7 +446,7 @@ static void write_pack_file(void)
{
uint32_t i = 0, j;
struct sha1file *f;
off_t offset, offset_one, last_obj_offset = 0;
off_t offset;
struct pack_header hdr;
uint32_t nr_remaining = nr_result;
time_t last_mtime = 0;
@@ -480,11 +478,8 @@ static void write_pack_file(void)
offset = sizeof(hdr);
nr_written = 0;
for (; i < nr_objects; i++) {
last_obj_offset = offset;
offset_one = write_one(f, objects + i, offset);
if (!offset_one)
if (!write_one(f, objects + i, &offset))
break;
offset = offset_one;
display_progress(progress_state, written);
}
@@ -497,9 +492,9 @@ static void write_pack_file(void)
} else if (nr_written == nr_remaining) {
sha1close(f, sha1, CSUM_FSYNC);
} else {
int fd = sha1close(f, NULL, 0);
fixup_pack_header_footer(fd, sha1, pack_tmp_name, nr_written);
fsync_or_die(fd, pack_tmp_name);
int fd = sha1close(f, sha1, 0);
fixup_pack_header_footer(fd, sha1, pack_tmp_name,
nr_written, sha1, offset);
close(fd);
}
@@ -1096,9 +1091,12 @@ static void check_object(struct object_entry *entry)
}
entry->type = sha1_object_info(entry->idx.sha1, &entry->size);
if (entry->type < 0)
die("unable to get type of object %s",
sha1_to_hex(entry->idx.sha1));
/*
* The error condition is checked in prepare_pack(). This is
* to permit a missing preferred base object to be ignored
* as a preferred base. Doing so can result in a larger
* pack file, but the transfer will still take place.
*/
}
static int pack_offset_sort(const void *_a, const void *_b)
@@ -1722,8 +1720,12 @@ static void prepare_pack(int window, int depth)
if (entry->no_try_delta)
continue;
if (!entry->preferred_base)
if (!entry->preferred_base) {
nr_deltas++;
if (entry->type < 0)
die("unable to get type of object %s",
sha1_to_hex(entry->idx.sha1));
}
delta_list[n++] = entry;
}

View File

@@ -194,6 +194,8 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix)
usage(read_tree_usage);
if ((opts.dir && !opts.update))
die("--exclude-per-directory is meaningless unless -u");
if (opts.merge && !opts.index_only)
setup_work_tree();
if (opts.merge) {
if (stage < 2)

View File

@@ -645,7 +645,8 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
revs.diff)
usage(rev_list_usage);
save_commit_buffer = revs.verbose_header || revs.grep_filter;
save_commit_buffer = revs.verbose_header ||
revs.grep_filter.pattern_list;
if (bisect_list)
revs.limited = 1;

View File

@@ -221,7 +221,7 @@ int cmd_rm(int argc, const char **argv, const char *prefix)
printf("rm '%s'\n", path);
if (remove_file_from_cache(path))
die("git-rm: unable to remove %s", path);
die("git rm: unable to remove %s", path);
}
if (show_only)
@@ -244,7 +244,7 @@ int cmd_rm(int argc, const char **argv, const char *prefix)
continue;
}
if (!removed)
die("git-rm: %s: %s", path, strerror(errno));
die("git rm: %s: %s", path, strerror(errno));
}
}

View File

@@ -62,7 +62,7 @@ match:
* ref points at a nonexistent object.
*/
if (!has_sha1_file(sha1))
die("git-show-ref: bad ref %s (%s)", refname,
die("git show-ref: bad ref %s (%s)", refname,
sha1_to_hex(sha1));
if (quiet)
@@ -82,12 +82,12 @@ match:
else {
obj = parse_object(sha1);
if (!obj)
die("git-show-ref: bad ref %s (%s)", refname,
die("git show-ref: bad ref %s (%s)", refname,
sha1_to_hex(sha1));
if (obj->type == OBJ_TAG) {
obj = deref_tag(obj, refname, 0);
if (!obj)
die("git-show-ref: bad tag at ref %s (%s)", refname,
die("git show-ref: bad tag at ref %s (%s)", refname,
sha1_to_hex(sha1));
hex = find_unique_abbrev(obj->sha1, abbrev);
printf("%s %s^{}\n", hex, refname);

View File

@@ -76,7 +76,7 @@ int cmd_get_tar_commit_id(int argc, const char **argv, const char *prefix)
n = read_in_full(0, buffer, HEADERSIZE);
if (n < HEADERSIZE)
die("git-get-tar-commit-id: read error");
die("git get-tar-commit-id: read error");
if (header->typeflag[0] != 'g')
return 1;
if (memcmp(content, "52 comment=", 11))
@@ -84,7 +84,7 @@ int cmd_get_tar_commit_id(int argc, const char **argv, const char *prefix)
n = write_in_full(1, content + 11, 41);
if (n < 41)
die("git-get-tar-commit-id: write error");
die("git get-tar-commit-id: write error");
return 0;
}

View File

@@ -262,7 +262,7 @@ static void chmod_path(int flip, const char *path)
report("chmod %cx '%s'", flip, path);
return;
fail:
die("git-update-index: cannot chmod %cx '%s'", flip, path);
die("git update-index: cannot chmod %cx '%s'", flip, path);
}
static void update_one(const char *path, const char *prefix, int prefix_length)
@@ -280,7 +280,7 @@ static void update_one(const char *path, const char *prefix, int prefix_length)
if (force_remove) {
if (remove_file_from_cache(p))
die("git-update-index: unable to remove %s", path);
die("git update-index: unable to remove %s", path);
report("remove '%s'", path);
goto free_return;
}
@@ -351,7 +351,7 @@ static void read_index_info(int line_termination)
if (line_termination && path_name[0] == '"') {
strbuf_reset(&uq);
if (unquote_c_style(&uq, path_name, NULL)) {
die("git-update-index: bad quoting of path name");
die("git update-index: bad quoting of path name");
}
path_name = uq.buf;
}
@@ -364,7 +364,7 @@ static void read_index_info(int line_termination)
if (!mode) {
/* mode == 0 means there is no such path -- remove */
if (remove_file_from_cache(path_name))
die("git-update-index: unable to remove %s",
die("git update-index: unable to remove %s",
ptr);
}
else {
@@ -374,7 +374,7 @@ static void read_index_info(int line_termination)
*/
ptr[-42] = ptr[-1] = 0;
if (add_cacheinfo(mode, sha1, path_name, stage))
die("git-update-index: unable to update %s",
die("git update-index: unable to update %s",
path_name);
}
continue;
@@ -614,10 +614,12 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)
continue;
}
if (!strcmp(path, "--refresh")) {
setup_work_tree();
has_errors |= refresh_cache(refresh_flags);
continue;
}
if (!strcmp(path, "--really-refresh")) {
setup_work_tree();
has_errors |= refresh_cache(REFRESH_REALLY | refresh_flags);
continue;
}
@@ -626,12 +628,12 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)
unsigned int mode;
if (i+3 >= argc)
die("git-update-index: --cacheinfo <mode> <sha1> <path>");
die("git update-index: --cacheinfo <mode> <sha1> <path>");
if (strtoul_ui(argv[i+1], 8, &mode) ||
get_sha1_hex(argv[i+2], sha1) ||
add_cacheinfo(mode, sha1, argv[i+3], 0))
die("git-update-index: --cacheinfo"
die("git update-index: --cacheinfo"
" cannot add %s", argv[i+3]);
i += 3;
continue;
@@ -639,7 +641,7 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)
if (!strcmp(path, "--chmod=-x") ||
!strcmp(path, "--chmod=+x")) {
if (argc <= i+1)
die("git-update-index: %s <path>", path);
die("git update-index: %s <path>", path);
set_executable_bit = path[8];
continue;
}
@@ -684,6 +686,7 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)
goto finish;
}
if (!strcmp(path, "--again") || !strcmp(path, "-g")) {
setup_work_tree();
has_errors = do_reupdate(argc - i, argv + i,
prefix, prefix_length);
if (has_errors)
@@ -702,6 +705,7 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)
usage(update_index_usage);
die("unknown option %s", path);
}
setup_work_tree();
p = prefix_path(prefix, prefix_length, path);
update_one(p, NULL, 0);
if (set_executable_bit)
@@ -714,6 +718,7 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)
strbuf_init(&buf, 0);
strbuf_init(&nbuf, 0);
setup_work_tree();
while (strbuf_getline(&buf, stdin, line_termination) != EOF) {
const char *p;
if (line_termination && buf.buf[0] == '"') {

View File

@@ -1,7 +1,7 @@
#include "builtin.h"
#include "cache.h"
#include "pack.h"
#include "pack-revindex.h"
#define MAX_CHAIN 50
@@ -129,6 +129,7 @@ int cmd_verify_pack(int argc, const char **argv, const char *prefix)
else {
if (verify_one_pack(argv[1], verbose))
err = 1;
discard_revindex();
nothing_done = 0;
}
argc--; argv++;

View File

@@ -500,6 +500,18 @@ static int hunk_comment_line(const char *bol)
return (isalpha(ch) || ch == '_' || ch == '$');
}
static void show_line_to_eol(const char *line, int len, const char *reset)
{
int saw_cr_at_eol = 0;
if (len < 0)
len = strlen(line);
saw_cr_at_eol = (len && line[len-1] == '\r');
printf("%.*s%s%s\n", len - saw_cr_at_eol, line,
reset,
saw_cr_at_eol ? "\r" : "");
}
static void dump_sline(struct sline *sline, unsigned long cnt, int num_parent,
int use_color)
{
@@ -593,7 +605,7 @@ static void dump_sline(struct sline *sline, unsigned long cnt, int num_parent,
else
putchar(' ');
}
printf("%s%s\n", ll->line, c_reset);
show_line_to_eol(ll->line, -1, c_reset);
ll = ll->next;
}
if (cnt < lno)
@@ -617,7 +629,7 @@ static void dump_sline(struct sline *sline, unsigned long cnt, int num_parent,
putchar(' ');
p_mask <<= 1;
}
printf("%.*s%s\n", sl->len, sl->bol, c_reset);
show_line_to_eol(sl->bol, sl->len, c_reset);
}
}
}

View File

@@ -67,7 +67,8 @@ extern int non_ascii(int);
struct rev_info; /* in revision.h, it circularly uses enum cmit_fmt */
extern void get_commit_format(const char *arg, struct rev_info *);
extern void format_commit_message(const struct commit *commit,
const void *format, struct strbuf *sb);
const void *format, struct strbuf *sb,
enum date_mode dmode);
extern void pretty_print_commit(enum cmit_fmt fmt, const struct commit*,
struct strbuf *,
int abbrev, const char *subject,

View File

@@ -97,7 +97,7 @@ int get_ack(int fd, unsigned char *result_sha1)
int len = packet_read_line(fd, line, sizeof(line));
if (!len)
die("git-fetch-pack: expected ACK/NAK, got EOF");
die("git fetch-pack: expected ACK/NAK, got EOF");
if (line[len-1] == '\n')
line[--len] = 0;
if (!strcmp(line, "NAK"))
@@ -109,7 +109,7 @@ int get_ack(int fd, unsigned char *result_sha1)
return 1;
}
}
die("git-fetch_pack: expected ACK/NAK, got '%s'", line);
die("git fetch_pack: expected ACK/NAK, got '%s'", line);
}
int path_match(const char *path, int nr, char **match)

View File

@@ -386,7 +386,9 @@ __git_porcelain_commands ()
cat-file) : plumbing;;
check-attr) : plumbing;;
check-ref-format) : plumbing;;
checkout-index) : plumbing;;
commit-tree) : plumbing;;
count-objects) : infrequent;;
cvsexportcommit) : export;;
cvsimport) : import;;
cvsserver) : daemon;;
@@ -395,6 +397,7 @@ __git_porcelain_commands ()
diff-index) : plumbing;;
diff-tree) : plumbing;;
fast-import) : import;;
fast-export) : export;;
fsck-objects) : plumbing;;
fetch-pack) : plumbing;;
fmt-merge-msg) : plumbing;;
@@ -404,6 +407,10 @@ __git_porcelain_commands ()
index-pack) : plumbing;;
init-db) : deprecated;;
local-fetch) : plumbing;;
lost-found) : infrequent;;
ls-files) : plumbing;;
ls-remote) : plumbing;;
ls-tree) : plumbing;;
mailinfo) : plumbing;;
mailsplit) : plumbing;;
merge-*) : plumbing;;
@@ -428,6 +435,7 @@ __git_porcelain_commands ()
runstatus) : plumbing;;
sh-setup) : internal;;
shell) : daemon;;
show-ref) : plumbing;;
send-pack) : plumbing;;
show-index) : plumbing;;
ssh-*) : transport;;
@@ -442,6 +450,8 @@ __git_porcelain_commands ()
upload-archive) : plumbing;;
upload-pack) : plumbing;;
write-tree) : plumbing;;
var) : infrequent;;
verify-pack) : infrequent;;
verify-tag) : plumbing;;
*) echo $i;;
esac

View File

@@ -42,11 +42,11 @@ int sha1close(struct sha1file *f, unsigned char *result, unsigned int flags)
sha1flush(f, offset);
f->offset = 0;
}
SHA1_Final(f->buffer, &f->ctx);
if (result)
hashcpy(result, f->buffer);
if (flags & (CSUM_CLOSE | CSUM_FSYNC)) {
/* write checksum and close fd */
SHA1_Final(f->buffer, &f->ctx);
if (result)
hashcpy(result, f->buffer);
sha1flush(f, 20);
if (flags & CSUM_FSYNC)
fsync_or_die(f->fd, f->name);

View File

@@ -5,6 +5,11 @@
*/
#include "cache.h"
/* Just so that no insane platform contaminate namespace with these symbols */
#undef SS
#undef AA
#undef DD
#define SS GIT_SPACE
#define AA GIT_ALPHA
#define DD GIT_DIGIT

26
diff.c
View File

@@ -511,13 +511,20 @@ const char *diff_get_color(int diff_use_color, enum color_diff ix)
static void emit_line(FILE *file, const char *set, const char *reset, const char *line, int len)
{
int has_trailing_newline = (len > 0 && line[len-1] == '\n');
int has_trailing_newline, has_trailing_carriage_return;
has_trailing_newline = (len > 0 && line[len-1] == '\n');
if (has_trailing_newline)
len--;
has_trailing_carriage_return = (len > 0 && line[len-1] == '\r');
if (has_trailing_carriage_return)
len--;
fputs(set, file);
fwrite(line, len, 1, file);
fputs(reset, file);
if (has_trailing_carriage_return)
fputc('\r', file);
if (has_trailing_newline)
fputc('\n', file);
}
@@ -1054,6 +1061,13 @@ static long gather_dirstat(FILE *file, struct dirstat_dir *dir, unsigned long ch
return this_dir;
}
static int dirstat_compare(const void *_a, const void *_b)
{
const struct dirstat_file *a = _a;
const struct dirstat_file *b = _b;
return strcmp(a->name, b->name);
}
static void show_dirstat(struct diff_options *options)
{
int i;
@@ -1065,7 +1079,7 @@ static void show_dirstat(struct diff_options *options)
dir.alloc = 0;
dir.nr = 0;
dir.percent = options->dirstat_percent;
dir.cumulative = options->output_format & DIFF_FORMAT_CUMULATIVE;
dir.cumulative = DIFF_OPT_TST(options, DIRSTAT_CUMULATIVE);
changed = 0;
for (i = 0; i < q->nr; i++) {
@@ -1113,6 +1127,7 @@ static void show_dirstat(struct diff_options *options)
return;
/* Show all directories with more than x% of the changes */
qsort(dir.files, dir.nr, sizeof(dir.files[0]), dirstat_compare);
gather_dirstat(options->file, &dir, changed, "", 0);
}
@@ -2290,6 +2305,7 @@ void diff_setup(struct diff_options *options)
options->break_opt = -1;
options->rename_limit = -1;
options->dirstat_percent = 3;
DIFF_OPT_CLR(options, DIRSTAT_CUMULATIVE);
options->context = 3;
options->change = diff_change;
@@ -2462,8 +2478,10 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac)
options->output_format |= DIFF_FORMAT_SHORTSTAT;
else if (opt_arg(arg, 'X', "dirstat", &options->dirstat_percent))
options->output_format |= DIFF_FORMAT_DIRSTAT;
else if (!strcmp(arg, "--cumulative"))
options->output_format |= DIFF_FORMAT_CUMULATIVE;
else if (!strcmp(arg, "--cumulative")) {
options->output_format |= DIFF_FORMAT_DIRSTAT;
DIFF_OPT_SET(options, DIRSTAT_CUMULATIVE);
}
else if (!strcmp(arg, "--check"))
options->output_format |= DIFF_FORMAT_CHECKDIFF;
else if (!strcmp(arg, "--summary"))

2
diff.h
View File

@@ -31,7 +31,6 @@ typedef void (*diff_format_fn_t)(struct diff_queue_struct *q,
#define DIFF_FORMAT_PATCH 0x0010
#define DIFF_FORMAT_SHORTSTAT 0x0020
#define DIFF_FORMAT_DIRSTAT 0x0040
#define DIFF_FORMAT_CUMULATIVE 0x0080
/* These override all above */
#define DIFF_FORMAT_NAME 0x0100
@@ -64,6 +63,7 @@ typedef void (*diff_format_fn_t)(struct diff_queue_struct *q,
#define DIFF_OPT_CHECK_FAILED (1 << 16)
#define DIFF_OPT_RELATIVE_NAME (1 << 17)
#define DIFF_OPT_IGNORE_SUBMODULES (1 << 18)
#define DIFF_OPT_DIRSTAT_CUMULATIVE (1 << 19)
#define DIFF_OPT_TST(opts, flag) ((opts)->flags & DIFF_OPT_##flag)
#define DIFF_OPT_SET(opts, flag) ((opts)->flags |= DIFF_OPT_##flag)
#define DIFF_OPT_CLR(opts, flag) ((opts)->flags &= ~DIFF_OPT_##flag)

20
entry.c
View File

@@ -111,7 +111,7 @@ static int write_entry(struct cache_entry *ce, char *path, const struct checkout
case S_IFREG:
new = read_blob_entry(ce, path, &size);
if (!new)
return error("git-checkout-index: unable to read sha1 file of %s (%s)",
return error("git checkout-index: unable to read sha1 file of %s (%s)",
path, sha1_to_hex(ce->sha1));
/*
@@ -132,7 +132,7 @@ static int write_entry(struct cache_entry *ce, char *path, const struct checkout
fd = create_file(path, ce->ce_mode);
if (fd < 0) {
free(new);
return error("git-checkout-index: unable to create file %s (%s)",
return error("git checkout-index: unable to create file %s (%s)",
path, strerror(errno));
}
@@ -140,12 +140,12 @@ static int write_entry(struct cache_entry *ce, char *path, const struct checkout
close(fd);
free(new);
if (wrote != size)
return error("git-checkout-index: unable to write file %s", path);
return error("git checkout-index: unable to write file %s", path);
break;
case S_IFLNK:
new = read_blob_entry(ce, path, &size);
if (!new)
return error("git-checkout-index: unable to read sha1 file of %s (%s)",
return error("git checkout-index: unable to read sha1 file of %s (%s)",
path, sha1_to_hex(ce->sha1));
if (to_tempfile || !has_symlinks) {
if (to_tempfile) {
@@ -155,31 +155,31 @@ static int write_entry(struct cache_entry *ce, char *path, const struct checkout
fd = create_file(path, 0666);
if (fd < 0) {
free(new);
return error("git-checkout-index: unable to create "
return error("git checkout-index: unable to create "
"file %s (%s)", path, strerror(errno));
}
wrote = write_in_full(fd, new, size);
close(fd);
free(new);
if (wrote != size)
return error("git-checkout-index: unable to write file %s",
return error("git checkout-index: unable to write file %s",
path);
} else {
wrote = symlink(new, path);
free(new);
if (wrote)
return error("git-checkout-index: unable to create "
return error("git checkout-index: unable to create "
"symlink %s (%s)", path, strerror(errno));
}
break;
case S_IFGITLINK:
if (to_tempfile)
return error("git-checkout-index: cannot create temporary subproject %s", path);
return error("git checkout-index: cannot create temporary subproject %s", path);
if (mkdir(path, 0777) < 0)
return error("git-checkout-index: cannot create subproject directory %s", path);
return error("git checkout-index: cannot create subproject directory %s", path);
break;
default:
return error("git-checkout-index: unknown file mode for %s", path);
return error("git checkout-index: unknown file mode for %s", path);
}
if (state->refresh_cache) {

View File

@@ -951,7 +951,8 @@ static void end_packfile(void)
close_pack_windows(pack_data);
fixup_pack_header_footer(pack_data->pack_fd, pack_data->sha1,
pack_data->pack_name, object_count);
pack_data->pack_name, object_count,
NULL, 0);
close(pack_data->pack_fd);
idx_name = keep_pack(create_index());

View File

@@ -1932,7 +1932,7 @@ proc show_more_context {} {
proc show_less_context {} {
global repo_config
if {$repo_config(gui.diffcontext) >= 1} {
if {$repo_config(gui.diffcontext) > 1} {
incr repo_config(gui.diffcontext) -1
reshow_diff
}

View File

@@ -175,7 +175,7 @@ proc show_diff {path w {lno {}} {scroll_pos {}}} {
lappend cmd -p
lappend cmd --no-color
if {$repo_config(gui.diffcontext) >= 0} {
if {$repo_config(gui.diffcontext) >= 1} {
lappend cmd "-U$repo_config(gui.diffcontext)"
}
if {$w eq $ui_index} {
@@ -192,6 +192,7 @@ proc show_diff {path w {lno {}} {scroll_pos {}}} {
return
}
set ::current_diff_inheader 1
fconfigure $fd \
-blocking 0 \
-encoding binary \
@@ -207,18 +208,21 @@ proc read_diff {fd scroll_pos} {
while {[gets $fd line] >= 0} {
# -- Cleanup uninteresting diff header lines.
#
if { [string match {diff --git *} $line]
|| [string match {diff --cc *} $line]
|| [string match {diff --combined *} $line]
|| [string match {--- *} $line]
|| [string match {+++ *} $line]} {
append current_diff_header $line "\n"
continue
if {$::current_diff_inheader} {
if { [string match {diff --git *} $line]
|| [string match {diff --cc *} $line]
|| [string match {diff --combined *} $line]
|| [string match {--- *} $line]
|| [string match {+++ *} $line]} {
append current_diff_header $line "\n"
continue
}
}
if {[string match {index *} $line]} continue
if {$line eq {deleted file mode 120000}} {
set line "deleted symlink"
}
set ::current_diff_inheader 0
# -- Automatically detect if this is a 3 way diff.
#

View File

@@ -125,7 +125,7 @@ proc do_options {} {
{b gui.matchtrackingbranch {mc "Match Tracking Branches"}}
{b gui.fastcopyblame {mc "Blame Copy Only On Changed Files"}}
{i-20..200 gui.copyblamethreshold {mc "Minimum Letters To Blame Copy On"}}
{i-0..99 gui.diffcontext {mc "Number of Diff Context Lines"}}
{i-1..99 gui.diffcontext {mc "Number of Diff Context Lines"}}
{i-0..99 gui.commitmsgwidth {mc "Commit Message Text Width"}}
{t gui.newbranchtemplate {mc "New Branch Name Template"}}
} {

File diff suppressed because it is too large Load Diff

View File

@@ -11,8 +11,8 @@ proc u2a {s} {
foreach i [split $s ""] {
scan $i %c c
if {$c<128} {
# escape '[', '\' and ']'
if {$c == 0x5b || $c == 0x5d} {
# escape '[', '\', '$' and ']'
if {$c == 0x5b || $c == 0x5d || $c == 0x24} {
append res "\\"
}
append res $i

View File

@@ -39,6 +39,7 @@ clear_stash () {
create_stash () {
stash_msg="$1"
git update-index -q --refresh
if no_changes
then
exit 0
@@ -101,6 +102,7 @@ save_stash () {
stash_msg="$*"
git update-index -q --refresh
if no_changes
then
echo 'No local changes to save'
@@ -150,6 +152,7 @@ show_stash () {
}
apply_stash () {
git update-index -q --refresh &&
git diff-files --quiet --ignore-submodules ||
die 'Cannot restore on top of a dirty state'

View File

@@ -3284,7 +3284,7 @@ sub close_file {
my $out = syswrite($tmp_fh, $str, $res);
defined($out) && $out == $res
or croak("write ",
$tmp_fh->filename,
Git::temp_path($tmp_fh),
": $!\n");
}
defined $res or croak $!;
@@ -3295,7 +3295,7 @@ sub close_file {
}
$hash = $::_repository->hash_and_insert_object(
$fh->filename);
Git::temp_path($fh));
$hash =~ /^[a-f\d]{40}$/ or die "not a sha1: $hash\n";
Git::temp_release($fb->{base}, 1);
@@ -4383,7 +4383,7 @@ sub config_pager {
sub run_pager {
return unless -t *STDOUT && defined $pager;
pipe my $rfd, my $wfd or return;
pipe my ($rfd, $wfd) or return;
defined(my $pid = fork) or ::fatal "Can't fork: $!";
if (!$pid) {
open STDOUT, '>&', $wfd or

2
git.c
View File

@@ -286,7 +286,7 @@ static void handle_internal_command(int argc, const char **argv)
{ "count-objects", cmd_count_objects, RUN_SETUP },
{ "describe", cmd_describe, RUN_SETUP },
{ "diff", cmd_diff },
{ "diff-files", cmd_diff_files, RUN_SETUP },
{ "diff-files", cmd_diff_files, RUN_SETUP | NEED_WORK_TREE },
{ "diff-index", cmd_diff_index, RUN_SETUP },
{ "diff-tree", cmd_diff_tree, RUN_SETUP },
{ "fast-export", cmd_fast_export, RUN_SETUP },

52
grep.c
View File

@@ -2,6 +2,19 @@
#include "grep.h"
#include "xdiff-interface.h"
void append_header_grep_pattern(struct grep_opt *opt, enum grep_header_field field, const char *pat)
{
struct grep_pat *p = xcalloc(1, sizeof(*p));
p->pattern = pat;
p->origin = "header";
p->no = 0;
p->token = GREP_PATTERN_HEAD;
p->field = field;
*opt->pattern_tail = p;
opt->pattern_tail = &p->next;
p->next = NULL;
}
void append_grep_pattern(struct grep_opt *opt, const char *pat,
const char *origin, int no, enum grep_pat_token t)
{
@@ -247,16 +260,53 @@ static int fixmatch(const char *pattern, char *line, regmatch_t *match)
}
}
static int strip_timestamp(char *bol, char **eol_p)
{
char *eol = *eol_p;
int ch;
while (bol < --eol) {
if (*eol != '>')
continue;
*eol_p = ++eol;
ch = *eol;
*eol = '\0';
return ch;
}
return 0;
}
static struct {
const char *field;
size_t len;
} header_field[] = {
{ "author ", 7 },
{ "committer ", 10 },
};
static int match_one_pattern(struct grep_opt *opt, struct grep_pat *p, char *bol, char *eol, enum grep_context ctx)
{
int hit = 0;
int at_true_bol = 1;
int saved_ch = 0;
regmatch_t pmatch[10];
if ((p->token != GREP_PATTERN) &&
((p->token == GREP_PATTERN_HEAD) != (ctx == GREP_CONTEXT_HEAD)))
return 0;
if (p->token == GREP_PATTERN_HEAD) {
const char *field;
size_t len;
assert(p->field < ARRAY_SIZE(header_field));
field = header_field[p->field].field;
len = header_field[p->field].len;
if (strncmp(bol, field, len))
return 0;
bol += len;
saved_ch = strip_timestamp(bol, &eol);
}
again:
if (!opt->fixed) {
regex_t *exp = &p->regexp;
@@ -298,6 +348,8 @@ static int match_one_pattern(struct grep_opt *opt, struct grep_pat *p, char *bol
goto again;
}
}
if (p->token == GREP_PATTERN_HEAD && saved_ch)
*eol = saved_ch;
return hit;
}

7
grep.h
View File

@@ -17,12 +17,18 @@ enum grep_context {
GREP_CONTEXT_BODY,
};
enum grep_header_field {
GREP_HEADER_AUTHOR = 0,
GREP_HEADER_COMMITTER,
};
struct grep_pat {
struct grep_pat *next;
const char *origin;
int no;
enum grep_pat_token token;
const char *pattern;
enum grep_header_field field;
regex_t regexp;
};
@@ -74,6 +80,7 @@ struct grep_opt {
};
extern void append_grep_pattern(struct grep_opt *opt, const char *pat, const char *origin, int no, enum grep_pat_token t);
extern void append_header_grep_pattern(struct grep_opt *, enum grep_header_field, const char *);
extern void compile_grep_patterns(struct grep_opt *opt);
extern void free_grep_patterns(struct grep_opt *opt);
extern int grep_buffer(struct grep_opt *opt, const char *name, char *buf, unsigned long size);

View File

@@ -654,7 +654,7 @@ static void parse_pack_objects(unsigned char *sha1)
}
}
static int write_compressed(int fd, void *in, unsigned int size, uint32_t *obj_crc)
static int write_compressed(struct sha1file *f, void *in, unsigned int size)
{
z_stream stream;
unsigned long maxsize;
@@ -674,13 +674,12 @@ static int write_compressed(int fd, void *in, unsigned int size, uint32_t *obj_c
deflateEnd(&stream);
size = stream.total_out;
write_or_die(fd, out, size);
*obj_crc = crc32(*obj_crc, out, size);
sha1write(f, out, size);
free(out);
return size;
}
static struct object_entry *append_obj_to_pack(
static struct object_entry *append_obj_to_pack(struct sha1file *f,
const unsigned char *sha1, void *buf,
unsigned long size, enum object_type type)
{
@@ -696,15 +695,15 @@ static struct object_entry *append_obj_to_pack(
s >>= 7;
}
header[n++] = c;
write_or_die(output_fd, header, n);
obj[0].idx.crc32 = crc32(0, Z_NULL, 0);
obj[0].idx.crc32 = crc32(obj[0].idx.crc32, header, n);
crc32_begin(f);
sha1write(f, header, n);
obj[0].size = size;
obj[0].hdr_size = n;
obj[0].type = type;
obj[0].real_type = type;
obj[1].idx.offset = obj[0].idx.offset + n;
obj[1].idx.offset += write_compressed(output_fd, buf, size, &obj[0].idx.crc32);
obj[1].idx.offset += write_compressed(f, buf, size);
obj[0].idx.crc32 = crc32_end(f);
hashcpy(obj->idx.sha1, sha1);
return obj;
}
@@ -716,7 +715,7 @@ static int delta_pos_compare(const void *_a, const void *_b)
return a->obj_no - b->obj_no;
}
static void fix_unresolved_deltas(int nr_unresolved)
static void fix_unresolved_deltas(struct sha1file *f, int nr_unresolved)
{
struct delta_entry **sorted_by_pos;
int i, n = 0;
@@ -754,8 +753,8 @@ static void fix_unresolved_deltas(int nr_unresolved)
if (check_sha1_signature(d->base.sha1, base_obj.data,
base_obj.size, typename(type)))
die("local object %s is corrupt", sha1_to_hex(d->base.sha1));
base_obj.obj = append_obj_to_pack(d->base.sha1, base_obj.data,
base_obj.size, type);
base_obj.obj = append_obj_to_pack(f, d->base.sha1,
base_obj.data, base_obj.size, type);
link_base_data(NULL, &base_obj);
find_delta_children(&d->base, &first, &last);
@@ -875,8 +874,10 @@ int main(int argc, char **argv)
const char *keep_name = NULL, *keep_msg = NULL;
char *index_name_buf = NULL, *keep_name_buf = NULL;
struct pack_idx_entry **idx_objects;
unsigned char sha1[20];
unsigned char pack_sha1[20];
int nongit = 0;
setup_git_directory_gently(&nongit);
git_config(git_index_pack_config, NULL);
for (i = 1; i < argc; i++) {
@@ -960,13 +961,15 @@ int main(int argc, char **argv)
parse_pack_header();
objects = xmalloc((nr_objects + 1) * sizeof(struct object_entry));
deltas = xmalloc(nr_objects * sizeof(struct delta_entry));
parse_pack_objects(sha1);
parse_pack_objects(pack_sha1);
if (nr_deltas == nr_resolved_deltas) {
stop_progress(&progress);
/* Flush remaining pack final 20-byte SHA1. */
flush();
} else {
if (fix_thin_pack) {
struct sha1file *f;
unsigned char read_sha1[20], tail_sha1[20];
char msg[48];
int nr_unresolved = nr_deltas - nr_resolved_deltas;
int nr_objects_initial = nr_objects;
@@ -975,12 +978,19 @@ int main(int argc, char **argv)
objects = xrealloc(objects,
(nr_objects + nr_unresolved + 1)
* sizeof(*objects));
fix_unresolved_deltas(nr_unresolved);
f = sha1fd(output_fd, curr_pack);
fix_unresolved_deltas(f, nr_unresolved);
sprintf(msg, "completed with %d local objects",
nr_objects - nr_objects_initial);
stop_progress_msg(&progress, msg);
fixup_pack_header_footer(output_fd, sha1,
curr_pack, nr_objects);
sha1close(f, tail_sha1, 0);
hashcpy(read_sha1, pack_sha1);
fixup_pack_header_footer(output_fd, pack_sha1,
curr_pack, nr_objects,
read_sha1, consumed_bytes-20);
if (hashcmp(read_sha1, tail_sha1) != 0)
die("Unexpected tail checksum for %s "
"(disk corruption?)", curr_pack);
}
if (nr_deltas != nr_resolved_deltas)
die("pack has %d unresolved deltas",
@@ -993,13 +1003,13 @@ int main(int argc, char **argv)
idx_objects = xmalloc((nr_objects) * sizeof(struct pack_idx_entry *));
for (i = 0; i < nr_objects; i++)
idx_objects[i] = &objects[i].idx;
curr_index = write_idx_file(index_name, idx_objects, nr_objects, sha1);
curr_index = write_idx_file(index_name, idx_objects, nr_objects, pack_sha1);
free(idx_objects);
final(pack_name, curr_pack,
index_name, curr_index,
keep_name, keep_msg,
sha1);
pack_sha1);
free(objects);
free(index_name_buf);
free(keep_name_buf);

View File

@@ -27,7 +27,7 @@ static int merge_entry(int pos, const char *path)
int found;
if (pos >= active_nr)
die("git-merge-index: %s not in the cache", path);
die("git merge-index: %s not in the cache", path);
arguments[0] = pgm;
arguments[1] = "";
arguments[2] = "";
@@ -53,7 +53,7 @@ static int merge_entry(int pos, const char *path)
arguments[stage + 4] = ownbuf[stage];
} while (++pos < active_nr);
if (!found)
die("git-merge-index: %s not in the cache", path);
die("git merge-index: %s not in the cache", path);
run_program();
return found;
}
@@ -117,7 +117,7 @@ int main(int argc, char **argv)
merge_all();
continue;
}
die("git-merge-index: unknown option %s", arg);
die("git merge-index: unknown option %s", arg);
}
merge_file(arg);
}

View File

@@ -142,3 +142,15 @@ struct revindex_entry *find_pack_revindex(struct packed_git *p, off_t ofs)
} while (lo < hi);
die("internal error: pack revindex corrupt");
}
void discard_revindex(void)
{
if (pack_revindex_hashsz) {
int i;
for (i = 0; i < pack_revindex_hashsz; i++)
if (pack_revindex[i].revindex)
free(pack_revindex[i].revindex);
free(pack_revindex);
pack_revindex_hashsz = 0;
}
}

View File

@@ -7,5 +7,6 @@ struct revindex_entry {
};
struct revindex_entry *find_pack_revindex(struct packed_git *p, off_t ofs);
void discard_revindex(void);
#endif

View File

@@ -144,41 +144,94 @@ char *write_idx_file(char *index_name, struct pack_idx_entry **objects,
return index_name;
}
/*
* Update pack header with object_count and compute new SHA1 for pack data
* associated to pack_fd, and write that SHA1 at the end. That new SHA1
* is also returned in new_pack_sha1.
*
* If partial_pack_sha1 is non null, then the SHA1 of the existing pack
* (without the header update) is computed and validated against the
* one provided in partial_pack_sha1. The validation is performed at
* partial_pack_offset bytes in the pack file. The SHA1 of the remaining
* data (i.e. from partial_pack_offset to the end) is then computed and
* returned in partial_pack_sha1.
*
* Note that new_pack_sha1 is updated last, so both new_pack_sha1 and
* partial_pack_sha1 can refer to the same buffer if the caller is not
* interested in the resulting SHA1 of pack data above partial_pack_offset.
*/
void fixup_pack_header_footer(int pack_fd,
unsigned char *pack_file_sha1,
unsigned char *new_pack_sha1,
const char *pack_name,
uint32_t object_count)
uint32_t object_count,
unsigned char *partial_pack_sha1,
off_t partial_pack_offset)
{
static const int buf_sz = 128 * 1024;
SHA_CTX c;
int aligned_sz, buf_sz = 8 * 1024;
SHA_CTX old_sha1_ctx, new_sha1_ctx;
struct pack_header hdr;
char *buf;
SHA1_Init(&old_sha1_ctx);
SHA1_Init(&new_sha1_ctx);
if (lseek(pack_fd, 0, SEEK_SET) != 0)
die("Failed seeking to start: %s", strerror(errno));
die("Failed seeking to start of %s: %s", pack_name, strerror(errno));
if (read_in_full(pack_fd, &hdr, sizeof(hdr)) != sizeof(hdr))
die("Unable to reread header of %s: %s", pack_name, strerror(errno));
if (lseek(pack_fd, 0, SEEK_SET) != 0)
die("Failed seeking to start: %s", strerror(errno));
die("Failed seeking to start of %s: %s", pack_name, strerror(errno));
SHA1_Update(&old_sha1_ctx, &hdr, sizeof(hdr));
hdr.hdr_entries = htonl(object_count);
SHA1_Update(&new_sha1_ctx, &hdr, sizeof(hdr));
write_or_die(pack_fd, &hdr, sizeof(hdr));
SHA1_Init(&c);
SHA1_Update(&c, &hdr, sizeof(hdr));
partial_pack_offset -= sizeof(hdr);
buf = xmalloc(buf_sz);
aligned_sz = buf_sz - sizeof(hdr);
for (;;) {
ssize_t n = xread(pack_fd, buf, buf_sz);
ssize_t m, n;
m = (partial_pack_sha1 && partial_pack_offset < aligned_sz) ?
partial_pack_offset : aligned_sz;
n = xread(pack_fd, buf, m);
if (!n)
break;
if (n < 0)
die("Failed to checksum %s: %s", pack_name, strerror(errno));
SHA1_Update(&c, buf, n);
SHA1_Update(&new_sha1_ctx, buf, n);
aligned_sz -= n;
if (!aligned_sz)
aligned_sz = buf_sz;
if (!partial_pack_sha1)
continue;
SHA1_Update(&old_sha1_ctx, buf, n);
partial_pack_offset -= n;
if (partial_pack_offset == 0) {
unsigned char sha1[20];
SHA1_Final(sha1, &old_sha1_ctx);
if (hashcmp(sha1, partial_pack_sha1) != 0)
die("Unexpected checksum for %s "
"(disk corruption?)", pack_name);
/*
* Now let's compute the SHA1 of the remainder of the
* pack, which also means making partial_pack_offset
* big enough not to matter anymore.
*/
SHA1_Init(&old_sha1_ctx);
partial_pack_offset = ~partial_pack_offset;
partial_pack_offset -= MSB(partial_pack_offset, 1);
}
}
free(buf);
SHA1_Final(pack_file_sha1, &c);
write_or_die(pack_fd, pack_file_sha1, 20);
if (partial_pack_sha1)
SHA1_Final(partial_pack_sha1, &old_sha1_ctx);
SHA1_Final(new_pack_sha1, &new_sha1_ctx);
write_or_die(pack_fd, new_pack_sha1, 20);
fsync_or_die(pack_fd, pack_name);
}
char *index_pack_lockfile(int ip_out)

2
pack.h
View File

@@ -58,7 +58,7 @@ struct pack_idx_entry {
extern char *write_idx_file(char *index_name, struct pack_idx_entry **objects, int nr_objects, unsigned char *sha1);
extern int check_pack_crc(struct packed_git *p, struct pack_window **w_curs, off_t offset, off_t len, unsigned int nr);
extern int verify_pack(struct packed_git *);
extern void fixup_pack_header_footer(int, unsigned char *, const char *, uint32_t);
extern void fixup_pack_header_footer(int, unsigned char *, const char *, uint32_t, unsigned char *, off_t);
extern char *index_pack_lockfile(int fd);
#define PH_ERROR_EOF (-1)

View File

@@ -58,7 +58,7 @@ require Exporter;
command_bidi_pipe command_close_bidi_pipe
version exec_path hash_object git_cmd_try
remote_refs
temp_acquire temp_release temp_reset);
temp_acquire temp_release temp_reset temp_path);
=head1 DESCRIPTION
@@ -937,7 +937,7 @@ sub _close_cat_blob {
{ # %TEMP_* Lexical Context
my (%TEMP_LOCKS, %TEMP_FILES);
my (%TEMP_FILEMAP, %TEMP_FILES);
=item temp_acquire ( NAME )
@@ -965,7 +965,7 @@ sub temp_acquire {
my $temp_fd = _temp_cache($name);
$TEMP_LOCKS{$temp_fd} = 1;
$TEMP_FILES{$temp_fd}{locked} = 1;
$temp_fd;
}
@@ -991,16 +991,16 @@ the same string.
sub temp_release {
my ($self, $temp_fd, $trunc) = _maybe_self(@_);
if (ref($temp_fd) ne 'File::Temp') {
if (exists $TEMP_FILEMAP{$temp_fd}) {
$temp_fd = $TEMP_FILES{$temp_fd};
}
unless ($TEMP_LOCKS{$temp_fd}) {
unless ($TEMP_FILES{$temp_fd}{locked}) {
carp "Attempt to release temp file '",
$temp_fd, "' that has not been locked";
}
temp_reset($temp_fd) if $trunc and $temp_fd->opened;
$TEMP_LOCKS{$temp_fd} = 0;
$TEMP_FILES{$temp_fd}{locked} = 0;
undef;
}
@@ -1009,9 +1009,9 @@ sub _temp_cache {
_verify_require();
my $temp_fd = \$TEMP_FILES{$name};
my $temp_fd = \$TEMP_FILEMAP{$name};
if (defined $$temp_fd and $$temp_fd->opened) {
if ($TEMP_LOCKS{$$temp_fd}) {
if ($TEMP_FILES{$$temp_fd}{locked}) {
throw Error::Simple("Temp file with moniker '",
$name, "' already in use");
}
@@ -1021,12 +1021,13 @@ sub _temp_cache {
carp "Temp file '", $name,
"' was closed. Opening replacement.";
}
$$temp_fd = File::Temp->new(
TEMPLATE => 'Git_XXXXXX',
DIR => File::Spec->tmpdir
my $fname;
($$temp_fd, $fname) = File::Temp->tempfile(
'Git_XXXXXX', UNLINK => 1
) or throw Error::Simple("couldn't open new temp file");
$$temp_fd->autoflush;
binmode $$temp_fd;
$TEMP_FILES{$$temp_fd}{fname} = $fname;
}
$$temp_fd;
}
@@ -1053,8 +1054,25 @@ sub temp_reset {
or throw Error::Simple("expected file position to be reset");
}
=item temp_path ( NAME )
=item temp_path ( FILEHANDLE )
Returns the filename associated with the given tempfile.
=cut
sub temp_path {
my ($self, $temp_fd) = _maybe_self(@_);
if (exists $TEMP_FILEMAP{$temp_fd}) {
$temp_fd = $TEMP_FILEMAP{$temp_fd};
}
$TEMP_FILES{$temp_fd}{fname};
}
sub END {
unlink values %TEMP_FILES if %TEMP_FILES;
unlink values %TEMP_FILEMAP if %TEMP_FILEMAP;
}
} # %TEMP_* Lexical Context

View File

@@ -310,7 +310,7 @@ static int mailmap_name(struct strbuf *sb, const char *email)
}
static size_t format_person_part(struct strbuf *sb, char part,
const char *msg, int len)
const char *msg, int len, enum date_mode dmode)
{
/* currently all placeholders have same length */
const int placeholder_len = 2;
@@ -377,7 +377,7 @@ static size_t format_person_part(struct strbuf *sb, char part,
switch (part) {
case 'd': /* date */
strbuf_addstr(sb, show_date(date, tz, DATE_NORMAL));
strbuf_addstr(sb, show_date(date, tz, dmode));
return placeholder_len;
case 'D': /* date, RFC2822 style */
strbuf_addstr(sb, show_date(date, tz, DATE_RFC2822));
@@ -409,6 +409,7 @@ struct chunk {
struct format_commit_context {
const struct commit *commit;
enum date_mode dmode;
/* These offsets are relative to the start of the commit message. */
int commit_header_parsed;
@@ -584,10 +585,12 @@ static size_t format_commit_item(struct strbuf *sb, const char *placeholder,
return 1;
case 'a': /* author ... */
return format_person_part(sb, placeholder[1],
msg + c->author.off, c->author.len);
msg + c->author.off, c->author.len,
c->dmode);
case 'c': /* committer ... */
return format_person_part(sb, placeholder[1],
msg + c->committer.off, c->committer.len);
msg + c->committer.off, c->committer.len,
c->dmode);
case 'e': /* encoding */
strbuf_add(sb, msg + c->encoding.off, c->encoding.len);
return 1;
@@ -599,12 +602,14 @@ static size_t format_commit_item(struct strbuf *sb, const char *placeholder,
}
void format_commit_message(const struct commit *commit,
const void *format, struct strbuf *sb)
const void *format, struct strbuf *sb,
enum date_mode dmode)
{
struct format_commit_context context;
memset(&context, 0, sizeof(context));
context.commit = commit;
context.dmode = dmode;
strbuf_expand(sb, format, format_commit_item, &context);
}
@@ -770,7 +775,7 @@ void pretty_print_commit(enum cmit_fmt fmt, const struct commit *commit,
const char *encoding;
if (fmt == CMIT_FMT_USERFORMAT) {
format_commit_message(commit, user_format, sb);
format_commit_message(commit, user_format, sb, dmode);
return;
}

View File

@@ -782,6 +782,10 @@ void init_revisions(struct rev_info *revs, const char *prefix)
revs->commit_format = CMIT_FMT_DEFAULT;
revs->grep_filter.status_only = 1;
revs->grep_filter.pattern_tail = &(revs->grep_filter.pattern_list);
revs->grep_filter.regflags = REG_NEWLINE;
diff_setup(&revs->diffopt);
if (prefix && !revs->diffopt.prefix) {
revs->diffopt.prefix = prefix;
@@ -946,33 +950,12 @@ void read_revisions_from_stdin(struct rev_info *revs)
static void add_grep(struct rev_info *revs, const char *ptn, enum grep_pat_token what)
{
if (!revs->grep_filter) {
struct grep_opt *opt = xcalloc(1, sizeof(*opt));
opt->status_only = 1;
opt->pattern_tail = &(opt->pattern_list);
opt->regflags = REG_NEWLINE;
revs->grep_filter = opt;
}
append_grep_pattern(revs->grep_filter, ptn,
"command line", 0, what);
append_grep_pattern(&revs->grep_filter, ptn, "command line", 0, what);
}
static void add_header_grep(struct rev_info *revs, const char *field, const char *pattern)
static void add_header_grep(struct rev_info *revs, enum grep_header_field field, const char *pattern)
{
char *pat;
const char *prefix;
int patlen, fldlen;
fldlen = strlen(field);
patlen = strlen(pattern);
pat = xmalloc(patlen + fldlen + 10);
prefix = ".*";
if (*pattern == '^') {
prefix = "";
pattern++;
}
sprintf(pat, "^%s %s%s", field, prefix, pattern);
add_grep(revs, pat, GREP_PATTERN_HEAD);
append_header_grep_pattern(&revs->grep_filter, field, pattern);
}
static void add_message_grep(struct rev_info *revs, const char *pattern)
@@ -1158,23 +1141,19 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg
* Grepping the commit log
*/
else if (!prefixcmp(arg, "--author=")) {
add_header_grep(revs, "author", arg+9);
add_header_grep(revs, GREP_HEADER_AUTHOR, arg+9);
} else if (!prefixcmp(arg, "--committer=")) {
add_header_grep(revs, "committer", arg+12);
add_header_grep(revs, GREP_HEADER_COMMITTER, arg+12);
} else if (!prefixcmp(arg, "--grep=")) {
add_message_grep(revs, arg+7);
} else if (!strcmp(arg, "--extended-regexp") || !strcmp(arg, "-E")) {
if (revs->grep_filter)
revs->grep_filter->regflags |= REG_EXTENDED;
revs->grep_filter.regflags |= REG_EXTENDED;
} else if (!strcmp(arg, "--regexp-ignore-case") || !strcmp(arg, "-i")) {
if (revs->grep_filter)
revs->grep_filter->regflags |= REG_ICASE;
revs->grep_filter.regflags |= REG_ICASE;
} else if (!strcmp(arg, "--fixed-strings") || !strcmp(arg, "-F")) {
if (revs->grep_filter)
revs->grep_filter->fixed = 1;
revs->grep_filter.fixed = 1;
} else if (!strcmp(arg, "--all-match")) {
if (revs->grep_filter)
revs->grep_filter->all_match = 1;
revs->grep_filter.all_match = 1;
} else if (!prefixcmp(arg, "--encoding=")) {
arg += 11;
if (strcmp(arg, "none"))
@@ -1349,9 +1328,7 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
if (diff_setup_done(&revs->diffopt) < 0)
die("diff_setup_done failed");
if (revs->grep_filter) {
compile_grep_patterns(revs->grep_filter);
}
compile_grep_patterns(&revs->grep_filter);
if (revs->reverse && revs->reflog_info)
die("cannot combine --reverse with --walk-reflogs");
@@ -1492,9 +1469,9 @@ static int rewrite_parents(struct rev_info *revs, struct commit *commit)
static int commit_match(struct commit *commit, struct rev_info *opt)
{
if (!opt->grep_filter)
if (!opt->grep_filter.pattern_list)
return 1;
return grep_buffer(opt->grep_filter,
return grep_buffer(&opt->grep_filter,
NULL, /* we say nothing, not even filename */
commit->buffer, strlen(commit->buffer));
}

View File

@@ -2,6 +2,7 @@
#define REVISION_H
#include "parse-options.h"
#include "grep.h"
#define SEEN (1u<<0)
#define UNINTERESTING (1u<<1)
@@ -92,7 +93,7 @@ struct rev_info {
int show_log_size;
/* Filter by commit log message */
struct grep_opt *grep_filter;
struct grep_opt grep_filter;
/* Display history graph */
struct git_graph *graph;

View File

@@ -581,6 +581,8 @@ const char *setup_git_directory(void)
if (retval && chdir(retval))
die ("Could not jump back into original cwd");
rel = get_relative_cwd(buffer, PATH_MAX, get_git_work_tree());
if (rel && *rel && chdir(get_git_work_tree()))
die ("Could not jump to working directory");
return rel && *rel ? strcat(rel, "/") : NULL;
}

View File

@@ -990,6 +990,7 @@ void prepare_packed_git(void)
void reprepare_packed_git(void)
{
discard_revindex();
prepare_packed_git_run_once = 0;
prepare_packed_git();
}

21
shell.c
View File

@@ -3,14 +3,6 @@
#include "exec_cmd.h"
#include "strbuf.h"
/* Stubs for functions that make no sense for git-shell. These stubs
* are provided here to avoid linking in external redundant modules.
*/
void release_pack_memory(size_t need, int fd){}
void trace_argv_printf(const char **argv, const char *fmt, ...){}
void trace_printf(const char *fmt, ...){}
static int do_generic_cmd(const char *me, char *arg)
{
const char *my_argv[4];
@@ -56,6 +48,19 @@ int main(int argc, char **argv)
{
char *prog;
struct commands *cmd;
int devnull_fd;
/*
* Always open file descriptors 0/1/2 to avoid clobbering files
* in die(). It also avoids not messing up when the pipes are
* dup'ed onto stdin/stdout/stderr in the child processes we spawn.
*/
devnull_fd = open("/dev/null", O_RDWR);
while (devnull_fd >= 0 && devnull_fd <= 2)
devnull_fd = dup(devnull_fd);
if (devnull_fd == -1)
die("opening /dev/null failed (%s)", strerror(errno));
close (devnull_fd);
/*
* Special hack to pretend to be a CVS server

View File

@@ -25,6 +25,7 @@ int recv_sideband(const char *me, int in_stream, int out, int err)
unsigned sf;
char buf[LARGE_PACKET_MAX + 2*FIX_SIZE];
char *suffix, *term;
int skip_pf = 0;
memcpy(buf, PREFIX, pf);
term = getenv("TERM");
@@ -54,39 +55,58 @@ int recv_sideband(const char *me, int in_stream, int out, int err)
return SIDEBAND_REMOTE_ERROR;
case 2:
buf[pf] = ' ';
len += pf+1;
while (1) {
int brk = pf+1;
do {
char *b = buf;
int brk = 0;
/* Break the buffer into separate lines. */
while (brk < len) {
/*
* If the last buffer didn't end with a line
* break then we should not print a prefix
* this time around.
*/
if (skip_pf) {
b += pf+1;
} else {
len += pf+1;
brk += pf+1;
}
/* Look for a line break. */
for (;;) {
brk++;
if (buf[brk-1] == '\n' ||
buf[brk-1] == '\r')
if (brk > len) {
brk = 0;
break;
}
if (b[brk-1] == '\n' ||
b[brk-1] == '\r')
break;
}
/*
* Let's insert a suffix to clear the end
* of the screen line, but only if current
* line data actually contains something.
* of the screen line if a line break was
* found. Also, if we don't skip the
* prefix, then a non-empty string must be
* present too.
*/
if (brk > pf+1 + 1) {
if (brk > (skip_pf ? 0 : (pf+1 + 1))) {
char save[FIX_SIZE];
memcpy(save, buf + brk, sf);
buf[brk + sf - 1] = buf[brk - 1];
memcpy(buf + brk - 1, suffix, sf);
safe_write(err, buf, brk + sf);
memcpy(buf + brk, save, sf);
} else
safe_write(err, buf, brk);
memcpy(save, b + brk, sf);
b[brk + sf - 1] = b[brk - 1];
memcpy(b + brk - 1, suffix, sf);
safe_write(err, b, brk + sf);
memcpy(b + brk, save, sf);
len -= brk;
} else {
int l = brk ? brk : len;
safe_write(err, b, l);
len -= l;
}
if (brk < len) {
memmove(buf + pf+1, buf + brk, len - brk);
len = len - brk + pf+1;
} else
break;
}
skip_pf = !brk;
memmove(buf + pf+1, b + brk, len);
} while (len);
continue;
case 1:
safe_write(out, buf + pf+1, len);

View File

@@ -85,7 +85,7 @@ $test_case 'add (with different case)' '
rm camelcase &&
echo 1 >CamelCase &&
git add CamelCase &&
test $(git-ls-files | grep -i camelcase | wc -l) = 1
test $(git ls-files | grep -i camelcase | wc -l) = 1
'

View File

@@ -1,6 +1,6 @@
#!/bin/sh
test_description="git-hash-object"
test_description="git hash-object"
. ./test-lib.sh

View File

@@ -78,7 +78,7 @@ test_expect_success 'git whatchanged -p --root' 'cmp whatchanged.expect whatchan
git tag my-first-tag
test_expect_success 'git tag my-first-tag' 'cmp .git/refs/heads/master .git/refs/tags/my-first-tag'
# TODO: test git-clone
# TODO: test git clone
git checkout -b mybranch
test_expect_success 'git checkout -b mybranch' 'cmp .git/refs/heads/master .git/refs/heads/mybranch'

View File

@@ -35,7 +35,7 @@ test_expect_success 'add key in different section' '
'
SECTION="test.q\"s\\sq'sp e.key"
test_expect_success 'make sure git-config escapes section names properly' '
test_expect_success 'make sure git config escapes section names properly' '
git config "$SECTION" bar &&
check "$SECTION" bar
'

View File

@@ -228,21 +228,21 @@ test_expect_success \
'echo TEST >F &&
git add F &&
GIT_AUTHOR_DATE="2005-05-26 23:30" \
GIT_COMMITTER_DATE="2005-05-26 23:30" git-commit -m add -a &&
GIT_COMMITTER_DATE="2005-05-26 23:30" git commit -m add -a &&
h_TEST=$(git rev-parse --verify HEAD)
echo The other day this did not work. >M &&
echo And then Bob told me how to fix it. >>M &&
echo OTHER >F &&
GIT_AUTHOR_DATE="2005-05-26 23:41" \
GIT_COMMITTER_DATE="2005-05-26 23:41" git-commit -F M -a &&
GIT_COMMITTER_DATE="2005-05-26 23:41" git commit -F M -a &&
h_OTHER=$(git rev-parse --verify HEAD) &&
GIT_AUTHOR_DATE="2005-05-26 23:44" \
GIT_COMMITTER_DATE="2005-05-26 23:44" git-commit --amend &&
GIT_COMMITTER_DATE="2005-05-26 23:44" git commit --amend &&
h_FIXED=$(git rev-parse --verify HEAD) &&
echo Merged initial commit and a later commit. >M &&
echo $h_TEST >.git/MERGE_HEAD &&
GIT_AUTHOR_DATE="2005-05-26 23:45" \
GIT_COMMITTER_DATE="2005-05-26 23:45" git-commit -F M &&
GIT_COMMITTER_DATE="2005-05-26 23:45" git commit -F M &&
h_MERGED=$(git rev-parse --verify HEAD) &&
rm -f M'
@@ -253,7 +253,7 @@ $h_OTHER $h_FIXED $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117151040 +0000 co
$h_FIXED $h_MERGED $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117151100 +0000 commit (merge): Merged initial commit and a later commit.
EOF
test_expect_success \
'git-commit logged updates' \
'git commit logged updates' \
"diff expect .git/logs/$m"
unset h_TEST h_OTHER h_FIXED h_MERGED

View File

@@ -28,6 +28,7 @@ test_rev_parse() {
[ $# -eq 0 ] && return
}
EMPTY_TREE=$(git write-tree)
mkdir -p work/sub/dir || exit 1
mv .git repo.git || exit 1
@@ -106,12 +107,71 @@ test_expect_success 'repo finds its work tree from work tree, too' '
'
test_expect_success '_gently() groks relative GIT_DIR & GIT_WORK_TREE' '
cd repo.git/work/sub/dir &&
(cd repo.git/work/sub/dir &&
GIT_DIR=../../.. GIT_WORK_TREE=../.. GIT_PAGER= \
git diff --exit-code tracked &&
echo changed > tracked &&
! GIT_DIR=../../.. GIT_WORK_TREE=../.. GIT_PAGER= \
git diff --exit-code tracked
git diff --exit-code tracked)
'
cat > diff-index-cached.expected <<\EOF
:000000 100644 0000000000000000000000000000000000000000 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 A sub/dir/tracked
EOF
cat > diff-index.expected <<\EOF
:000000 100644 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000 A sub/dir/tracked
EOF
test_expect_success 'git diff-index' '
GIT_DIR=repo.git GIT_WORK_TREE=repo.git/work git diff-index $EMPTY_TREE > result &&
test_cmp diff-index.expected result &&
GIT_DIR=repo.git git diff-index --cached $EMPTY_TREE > result &&
test_cmp diff-index-cached.expected result
'
cat >diff-files.expected <<\EOF
:100644 100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0000000000000000000000000000000000000000 M sub/dir/tracked
EOF
test_expect_success 'git diff-files' '
GIT_DIR=repo.git GIT_WORK_TREE=repo.git/work git diff-files > result &&
test_cmp diff-files.expected result
'
cat >diff-TREE.expected <<\EOF
diff --git a/sub/dir/tracked b/sub/dir/tracked
new file mode 100644
index 0000000..5ea2ed4
--- /dev/null
+++ b/sub/dir/tracked
@@ -0,0 +1 @@
+changed
EOF
cat >diff-TREE-cached.expected <<\EOF
diff --git a/sub/dir/tracked b/sub/dir/tracked
new file mode 100644
index 0000000..e69de29
EOF
cat >diff-FILES.expected <<\EOF
diff --git a/sub/dir/tracked b/sub/dir/tracked
index e69de29..5ea2ed4 100644
--- a/sub/dir/tracked
+++ b/sub/dir/tracked
@@ -0,0 +1 @@
+changed
EOF
test_expect_success 'git diff' '
GIT_DIR=repo.git GIT_WORK_TREE=repo.git/work git diff $EMPTY_TREE > result &&
test_cmp diff-TREE.expected result &&
GIT_DIR=repo.git git diff --cached $EMPTY_TREE > result &&
test_cmp diff-TREE-cached.expected result &&
GIT_DIR=repo.git GIT_WORK_TREE=repo.git/work git diff > result &&
test_cmp diff-FILES.expected result
'
test_expect_success 'git grep' '
(cd repo.git/work/sub &&
GIT_DIR=../.. GIT_WORK_TREE=.. git grep -l changed | grep -q dir/tracked)
'
test_done

View File

@@ -23,7 +23,7 @@ add_line_into_file()
fi
test_tick
git-commit --quiet -m "$MSG" $_file
git commit --quiet -m "$MSG" $_file
}
HASH1=

View File

@@ -13,7 +13,7 @@ file if core.symlinks is false.'
test_expect_success \
'preparation' '
git config core.symlinks false &&
l=$(echo -n file | git-hash-object -t blob -w --stdin) &&
l=$(echo -n file | git hash-object -t blob -w --stdin) &&
echo "120000 $l symlink" | git update-index --index-info'
test_expect_success \
@@ -23,6 +23,6 @@ test -f symlink'
test_expect_success \
'the file must be the blob we added during the setup' '
test "$(git-hash-object -t blob symlink)" = $l'
test "$(git hash-object -t blob symlink)" = $l'
test_done

View File

@@ -26,8 +26,8 @@ chmod +x .git/hooks/post-commit'
test_expect_success 'post-commit hook used ordinarily' '
echo initial >top &&
git-add top
git-commit -m initial &&
git add top
git commit -m initial &&
test -r "${COMMIT_FILE}"
'

View File

@@ -40,7 +40,7 @@ test_expect_success 'update-index --remove --again' \
git ls-files -s >current &&
cmp current expected'
test_expect_success 'first commit' 'git-commit -m initial'
test_expect_success 'first commit' 'git commit -m initial'
cat > expected <<\EOF
100644 53ab446c3f4e42ce9bb728a0ccb283a101be4979 0 dir1/file3

View File

@@ -13,7 +13,7 @@ even if a plain file is in the working tree if core.symlinks is false.'
test_expect_success \
'preparation' '
git config core.symlinks false &&
l=$(echo -n file | git-hash-object -t blob -w --stdin) &&
l=$(echo -n file | git hash-object -t blob -w --stdin) &&
echo "120000 $l symlink" | git update-index --index-info'
test_expect_success \

Some files were not shown because too many files have changed in this diff Show More