mirror of
https://github.com/git/git.git
synced 2026-03-13 10:23:30 +01:00
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:
87
Documentation/RelNotes-1.6.0.2.txt
Normal file
87
Documentation/RelNotes-1.6.0.2.txt
Normal 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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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[]
|
||||
|
||||
@@ -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
|
||||
----------
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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'
|
||||
----------------------------------------------------------------
|
||||
|
||||
@@ -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
|
||||
--------
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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
|
||||
-------
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -7,7 +7,7 @@ gitmodules - defining submodule properties
|
||||
|
||||
SYNOPSIS
|
||||
--------
|
||||
gitmodules
|
||||
$GIT_WORK_DIR/.gitmodules
|
||||
|
||||
|
||||
DESCRIPTION
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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::
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/bin/sh
|
||||
|
||||
GVF=GIT-VERSION-FILE
|
||||
DEF_VER=v1.6.0.GIT
|
||||
DEF_VER=v1.6.0.2.GIT
|
||||
|
||||
LF='
|
||||
'
|
||||
|
||||
42
Makefile
42
Makefile
@@ -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*
|
||||
|
||||
2
RelNotes
2
RelNotes
@@ -1 +1 @@
|
||||
Documentation/RelNotes-1.6.0.1.txt
|
||||
Documentation/RelNotes-1.6.0.2.txt
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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]);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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++;
|
||||
}
|
||||
|
||||
@@ -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++)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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.");
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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] == '"') {
|
||||
|
||||
@@ -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++;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
3
commit.h
3
commit.h
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
5
ctype.c
5
ctype.c
@@ -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
26
diff.c
@@ -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
2
diff.h
@@ -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
20
entry.c
@@ -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) {
|
||||
|
||||
@@ -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());
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
#
|
||||
|
||||
@@ -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"}}
|
||||
} {
|
||||
|
||||
918
git-gui/po/fr.po
918
git-gui/po/fr.po
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
|
||||
@@ -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'
|
||||
|
||||
|
||||
@@ -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
2
git.c
@@ -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
52
grep.c
@@ -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
7
grep.h
@@ -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);
|
||||
|
||||
46
index-pack.c
46
index-pack.c
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
79
pack-write.c
79
pack-write.c
@@ -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
2
pack.h
@@ -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)
|
||||
|
||||
42
perl/Git.pm
42
perl/Git.pm
@@ -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
|
||||
|
||||
17
pretty.c
17
pretty.c
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
55
revision.c
55
revision.c
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
2
setup.c
2
setup.c
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
21
shell.c
@@ -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
|
||||
|
||||
66
sideband.c
66
sideband.c
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
'
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
test_description="git-hash-object"
|
||||
test_description="git hash-object"
|
||||
|
||||
. ./test-lib.sh
|
||||
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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
|
||||
'
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -23,7 +23,7 @@ add_line_into_file()
|
||||
fi
|
||||
|
||||
test_tick
|
||||
git-commit --quiet -m "$MSG" $_file
|
||||
git commit --quiet -m "$MSG" $_file
|
||||
}
|
||||
|
||||
HASH1=
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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}"
|
||||
'
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user