summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/diff-options.txt11
-rw-r--r--Makefile7
-rw-r--r--commit-tree.c4
-rw-r--r--count-delta.c13
-rw-r--r--delta.h10
-rwxr-xr-xgit-commit.sh305
-rwxr-xr-xgit-status.sh115
-rw-r--r--ident.c5
-rw-r--r--index-pack.c6
-rw-r--r--ls-files.c22
-rw-r--r--pack-check.c6
-rw-r--r--pack.h1
-rw-r--r--patch-delta.c5
-rw-r--r--rev-list.c16
-rw-r--r--sha1_file.c15
-rw-r--r--show-branch.c2
-rwxr-xr-xt/t6000lib.sh7
-rw-r--r--unpack-objects.c5
18 files changed, 338 insertions, 217 deletions
diff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt
index 5c85167..2a0275e 100644
--- a/Documentation/diff-options.txt
+++ b/Documentation/diff-options.txt
@@ -35,6 +35,17 @@
-C::
Detect copies as well as renames.
+--diff-filter=[ACDMRTUXB*]::
+ Select only files that are Added (`A`), Copied (`C`),
+ Deleted (`D`), Modified (`M`), Renamed (`R`), have their
+ type (mode) changed (`T`), are Unmerged (`U`), are
+ Unknown (`X`), or have had their pairing Broken (`B`).
+ Any combination of the filter characters may be used.
+ When `*` (All-or-none) is added to the combination, all
+ paths are selected if there is any file that matches
+ other criteria in the comparison; if there is no file
+ that matches other criteria, nothing is selected.
+
--find-copies-harder::
For performance reasons, by default, -C option finds copies only
if the original file of the copy was modified in the same
diff --git a/Makefile b/Makefile
index 5c32934..f240e45 100644
--- a/Makefile
+++ b/Makefile
@@ -107,7 +107,7 @@ SCRIPT_SH = \
git-merge-one-file.sh git-parse-remote.sh \
git-prune.sh git-pull.sh git-push.sh git-rebase.sh \
git-repack.sh git-request-pull.sh git-reset.sh \
- git-resolve.sh git-revert.sh git-sh-setup.sh git-status.sh \
+ git-resolve.sh git-revert.sh git-sh-setup.sh \
git-tag.sh git-verify-tag.sh git-whatchanged.sh \
git-applymbox.sh git-applypatch.sh git-am.sh \
git-merge.sh git-merge-stupid.sh git-merge-octopus.sh \
@@ -125,7 +125,7 @@ SCRIPT_PYTHON = \
SCRIPTS = $(patsubst %.sh,%,$(SCRIPT_SH)) \
$(patsubst %.perl,%,$(SCRIPT_PERL)) \
$(patsubst %.py,%,$(SCRIPT_PYTHON)) \
- git-cherry-pick git-show
+ git-cherry-pick git-show git-status
# The ones that do not have to link with lcrypto nor lz.
SIMPLE_PROGRAMS = \
@@ -443,6 +443,9 @@ git-cherry-pick: git-revert
git-show: git-whatchanged
cp $< $@
+git-status: git-commit
+ cp $< $@
+
# These can record GIT_VERSION
git$X git.spec \
$(patsubst %.sh,%,$(SCRIPT_SH)) \
diff --git a/commit-tree.c b/commit-tree.c
index 4634b50..b1c8dca 100644
--- a/commit-tree.c
+++ b/commit-tree.c
@@ -86,13 +86,13 @@ int main(int argc, char **argv)
unsigned int size;
setup_ident();
+ setup_git_directory();
+
git_config(git_default_config);
if (argc < 2 || get_sha1_hex(argv[1], tree_sha1) < 0)
usage(commit_tree_usage);
- setup_git_directory();
-
check_valid(tree_sha1, "tree");
for (i = 2; i < argc; i += 2) {
char *a, *b;
diff --git a/count-delta.c b/count-delta.c
index 7559ff6..058a2aa 100644
--- a/count-delta.c
+++ b/count-delta.c
@@ -16,11 +16,7 @@
*
* Number of bytes that are _not_ copied from the source is deletion,
* and number of inserted literal bytes are addition, so sum of them
- * is the extent of damage. xdelta can express an edit that copies
- * data inside of the destination which originally came from the
- * source. We do not count that in the following routine, so we are
- * undercounting the source material that remains in the final output
- * that way.
+ * is the extent of damage.
*/
int count_delta(void *delta_buf, unsigned long delta_size,
unsigned long *src_copied, unsigned long *literal_added)
@@ -50,13 +46,10 @@ int count_delta(void *delta_buf, unsigned long delta_size,
if (cmd & 0x08) cp_off |= (*data++ << 24);
if (cmd & 0x10) cp_size = *data++;
if (cmd & 0x20) cp_size |= (*data++ << 8);
+ if (cmd & 0x40) cp_size |= (*data++ << 16);
if (cp_size == 0) cp_size = 0x10000;
- if (cmd & 0x40)
- /* copy from dst */
- ;
- else
- copied_from_source += cp_size;
+ copied_from_source += cp_size;
out += cp_size;
} else {
/* write literal into dst */
diff --git a/delta.h b/delta.h
index 31d1820..a15350d 100644
--- a/delta.h
+++ b/delta.h
@@ -19,14 +19,14 @@ extern void *patch_delta(void *src_buf, unsigned long src_size,
static inline unsigned long get_delta_hdr_size(const unsigned char **datap)
{
const unsigned char *data = *datap;
- unsigned char cmd = *data++;
- unsigned long size = cmd & ~0x80;
- int i = 7;
- while (cmd & 0x80) {
+ unsigned char cmd;
+ unsigned long size = 0;
+ int i = 0;
+ do {
cmd = *data++;
size |= (cmd & ~0x80) << i;
i += 7;
- }
+ } while (cmd & 0x80);
*datap = data;
return size;
}
diff --git a/git-commit.sh b/git-commit.sh
index 2538924..073ec81 100755
--- a/git-commit.sh
+++ b/git-commit.sh
@@ -3,13 +3,21 @@
# Copyright (c) 2005 Linus Torvalds
# Copyright (c) 2006 Junio C Hamano
-USAGE='[-a] [-i] [-s] [-v | --no-verify] [-m <message> | -F <logfile> | (-C|-c) <commit>] [-e] [--author <author>] [<path>...]'
-
+USAGE='[-a] [-i] [-s] [-v] [--no-verify] [-m <message> | -F <logfile> | (-C|-c) <commit>] [-e] [--author <author>] [<path>...]'
SUBDIRECTORY_OK=Yes
. git-sh-setup
-git-rev-parse --verify HEAD >/dev/null 2>&1 ||
-initial_commit=t
+git-rev-parse --verify HEAD >/dev/null 2>&1 || initial_commit=t
+branch=$(GIT_DIR="$GIT_DIR" git-symbolic-ref HEAD)
+
+case "$0" in
+*status)
+ status_only=t
+ unmerged_ok_if_status=--unmerged ;;
+*commit)
+ status_only=
+ unmerged_ok_if_status= ;;
+esac
refuse_partial () {
echo >&2 "$1"
@@ -17,23 +25,149 @@ refuse_partial () {
exit 1
}
-SAVE_INDEX="$GIT_DIR/save-index$$"
+THIS_INDEX="$GIT_DIR/index"
+NEXT_INDEX="$GIT_DIR/next-index$$"
+rm -f "$NEXT_INDEX"
save_index () {
- cp "$GIT_DIR/index" "$SAVE_INDEX"
+ cp "$THIS_INDEX" "$NEXT_INDEX"
+}
+
+report () {
+ header="#
+# $1:
+# ($2)
+#
+"
+ trailer=""
+ while read status name newname
+ do
+ printf '%s' "$header"
+ header=""
+ trailer="#
+"
+ case "$status" in
+ M ) echo "# modified: $name";;
+ D*) echo "# deleted: $name";;
+ T ) echo "# typechange: $name";;
+ C*) echo "# copied: $name -> $newname";;
+ R*) echo "# renamed: $name -> $newname";;
+ A*) echo "# new file: $name";;
+ U ) echo "# unmerged: $name";;
+ esac
+ done
+ printf '%s' "$trailer"
+ [ "$header" ]
}
run_status () {
- (
- cd "$TOP"
- if test '' != "$TMP_INDEX"
- then
- GIT_INDEX_FILE="$TMP_INDEX" git-status
- else
- git-status
- fi
- )
+ (
+ # We always show status for the whole tree.
+ cd "$TOP"
+
+ # If TMP_INDEX is defined, that means we are doing
+ # "--only" partial commit, and that index file is used
+ # to build the tree for the commit. Otherwise, if
+ # NEXT_INDEX exists, that is the index file used to
+ # make the commit. Otherwise we are using as-is commit
+ # so the regular index file is what we use to compare.
+ if test '' != "$TMP_INDEX"
+ then
+ GIT_INDEX_FILE="$TMP_INDEX"
+ export GIT_INDEX_FILE
+ elif test -f "$NEXT_INDEX"
+ then
+ GIT_INDEX_FILE="$NEXT_INDEX"
+ export GIT_INDEX_FILE
+ fi
+
+ case "$branch" in
+ refs/heads/master) ;;
+ *) echo "# On branch $branch" ;;
+ esac
+
+ if test -z "$initial_commit"
+ then
+ git-diff-index -M --cached --name-status \
+ --diff-filter=MDTCRA HEAD |
+ sed -e '
+ s/\\/\\\\/g
+ s/ /\\ /g
+ ' |
+ report "Updated but not checked in" "will commit"
+ committable="$?"
+ else
+ echo '#
+# Initial commit
+#'
+ git-ls-files |
+ sed -e '
+ s/\\/\\\\/g
+ s/ /\\ /g
+ s/^/A /
+ ' |
+ report "Updated but not checked in" "will commit"
+
+ committable="$?"
+ fi
+
+ git-diff-files --name-status |
+ sed -e '
+ s/\\/\\\\/g
+ s/ /\\ /g
+ ' |
+ report "Changed but not updated" \
+ "use git-update-index to mark for commit"
+
+ if test -f "$GIT_DIR/info/exclude"
+ then
+ git-ls-files -z --others --directory \
+ --exclude-from="$GIT_DIR/info/exclude" \
+ --exclude-per-directory=.gitignore
+ else
+ git-ls-files -z --others --directory \
+ --exclude-per-directory=.gitignore
+ fi |
+ perl -e '$/ = "\0";
+ my $shown = 0;
+ while (<>) {
+ chomp;
+ s|\\|\\\\|g;
+ s|\t|\\t|g;
+ s|\n|\\n|g;
+ s/^/# /;
+ if (!$shown) {
+ print "#\n# Untracked files:\n";
+ print "# (use \"git add\" to add to commit)\n";
+ print "#\n";
+ $shown = 1;
+ }
+ print "$_\n";
+ }
+ '
+
+ if test -n "$verbose"
+ then
+ git-diff-index --cached -M -p --diff-filter=MDTCRA HEAD
+ fi
+ case "$committable" in
+ 0)
+ echo "nothing to commit"
+ exit 1
+ esac
+ exit 0
+ )
}
+trap '
+ test -z "$TMP_INDEX" || {
+ test -f "$TMP_INDEX" && rm -f "$TMP_INDEX"
+ }
+ rm -f "$NEXT_INDEX"
+' 0
+
+################################################################
+# Command line argument parsing and sanity checking
+
all=
also=
only=
@@ -43,6 +177,7 @@ no_edit=
log_given=
log_message=
verify=t
+verbose=
signoff=
force_author=
while case "$#" in 0) break;; esac
@@ -172,9 +307,9 @@ do
signoff=t
shift
;;
- -v|--v|--ve|--ver|--veri|--verif|--verify)
- verify=t
- shift
+ -v|--v|--ve|--ver|--verb|--verbo|--verbos|--verbose)
+ verbose=t
+ shift
;;
--)
shift
@@ -189,6 +324,9 @@ do
esac
done
+################################################################
+# Sanity check options
+
case "$log_given" in
tt*)
die "Only one of -c/-C/-F/-m can be used." ;;
@@ -207,9 +345,24 @@ case "$#,$also$only" in
# Later when switch the defaults, we will replace them with these:
# echo >&2 "assuming --only paths..."
# also=
+
+ # If we are going to launch an editor, the message won't be
+ # shown without this...
+ test -z "$log_given$status_only" && sleep 1
;;
esac
unset only
+case "$all,$also,$#" in
+t,t,*)
+ die "Cannot use -a and -i at the same time." ;;
+t,,[1-9]*)
+ die "Paths with -a does not make sense." ;;
+,t,0)
+ die "No paths with -i does not make sense." ;;
+esac
+
+################################################################
+# Prepare index to have a tree to be committed
TOP=`git-rev-parse --show-cdup`
if test -z "$TOP"
@@ -218,29 +371,25 @@ then
fi
case "$all,$also" in
-t,t)
- die "Cannot use -a and -i at the same time." ;;
t,)
- case "$#" in
- 0) ;;
- *) die "Paths with -a does not make sense." ;;
- esac
-
save_index &&
(
cd "$TOP"
+ GIT_INDEX_FILE="$NEXT_INDEX"
+ export GIT_INDEX_FILE
git-diff-files --name-only -z |
git-update-index --remove -z --stdin
)
;;
,t)
- case "$#" in
- 0) die "No paths with -i does not make sense." ;;
- esac
-
save_index &&
git-diff-files --name-only -z -- "$@" |
- (cd "$TOP" && git-update-index --remove -z --stdin)
+ (
+ cd "$TOP"
+ GIT_INDEX_FILE="$NEXT_INDEX"
+ export GIT_INDEX_FILE
+ git-update-index --remove -z --stdin
+ )
;;
,)
case "$#" in
@@ -262,43 +411,68 @@ t,)
refuse_partial "Different in index and the last commit:
$dirty_in_index"
fi
- commit_only=`git-ls-files -- "$@"` ;;
+ commit_only=`git-ls-files -- "$@"`
+
+ # Build the temporary index and update the real index
+ # the same way.
+ if test -z "$initial_commit"
+ then
+ cp "$THIS_INDEX" "$TMP_INDEX"
+ GIT_INDEX_FILE="$TMP_INDEX" git-read-tree -m HEAD
+ else
+ rm -f "$TMP_INDEX"
+ fi || exit
+
+ echo "$commit_only" |
+ GIT_INDEX_FILE="$TMP_INDEX" \
+ git-update-index --add --remove --stdin &&
+
+ save_index &&
+ echo "$commit_only" |
+ (
+ GIT_INDEX_FILE="$NEXT_INDEX"
+ export GIT_INDEX_FILE
+ git-update-index --remove --stdin
+ ) || exit
+ ;;
esac
;;
esac
-git-update-index -q --refresh || exit 1
-
-trap '
- test -z "$TMP_INDEX" || {
- test -f "$TMP_INDEX" && rm -f "$TMP_INDEX"
- }
- test -f "$SAVE_INDEX" && mv -f "$SAVE_INDEX" "$GIT_DIR/index"
-' 0
+################################################################
+# If we do as-is commit, the index file will be THIS_INDEX,
+# otherwise NEXT_INDEX after we make this commit. We leave
+# the index as is if we abort.
-if test "$TMP_INDEX"
+if test -f "$NEXT_INDEX"
then
- if test -z "$initial_commit"
- then
- GIT_INDEX_FILE="$TMP_INDEX" git-read-tree HEAD
- else
- rm -f "$TMP_INDEX"
- fi || exit
- echo "$commit_only" |
- GIT_INDEX_FILE="$TMP_INDEX" git-update-index --add --remove --stdin &&
- save_index &&
- echo "$commit_only" |
- git-update-index --remove --stdin ||
- exit
+ USE_INDEX="$NEXT_INDEX"
+else
+ USE_INDEX="$THIS_INDEX"
fi
+GIT_INDEX_FILE="$USE_INDEX" \
+ git-update-index -q $unmerged_ok_if_status --refresh || exit
+
+################################################################
+# If the request is status, just show it and exit.
+
+case "$0" in
+*status)
+ run_status
+ exit $?
+esac
+
+################################################################
+# Grab commit message, write out tree and make commit.
+
if test t = "$verify" && test -x "$GIT_DIR"/hooks/pre-commit
then
if test "$TMP_INDEX"
then
GIT_INDEX_FILE="$TMP_INDEX" "$GIT_DIR"/hooks/pre-commit
else
- "$GIT_DIR"/hooks/pre-commit
+ GIT_INDEX_FILE="$USE_INDEX" "$GIT_DIR"/hooks/pre-commit
fi || exit
fi
@@ -398,7 +572,6 @@ else
PARENTS=""
fi
-
run_status >>"$GIT_DIR"/COMMIT_EDITMSG
if [ "$?" != "0" -a ! -f "$GIT_DIR/MERGE_HEAD" ]
then
@@ -429,8 +602,14 @@ t)
fi
esac
-grep -v '^#' < "$GIT_DIR"/COMMIT_EDITMSG |
-git-stripspace > "$GIT_DIR"/COMMIT_MSG
+sed -e '
+ /^diff --git a\/.*/{
+ s///
+ q
+ }
+ /^#/d
+' "$GIT_DIR"/COMMIT_EDITMSG |
+git-stripspace >"$GIT_DIR"/COMMIT_MSG
if cnt=`grep -v -i '^Signed-off-by' "$GIT_DIR"/COMMIT_MSG |
git-stripspace |
@@ -439,14 +618,20 @@ if cnt=`grep -v -i '^Signed-off-by' "$GIT_DIR"/COMMIT_MSG |
then
if test -z "$TMP_INDEX"
then
- tree=$(git-write-tree)
+ tree=$(GIT_INDEX_FILE="$USE_INDEX" git-write-tree)
else
tree=$(GIT_INDEX_FILE="$TMP_INDEX" git-write-tree) &&
rm -f "$TMP_INDEX"
fi &&
commit=$(cat "$GIT_DIR"/COMMIT_MSG | git-commit-tree $tree $PARENTS) &&
git-update-ref HEAD $commit $current &&
- rm -f -- "$GIT_DIR/MERGE_HEAD"
+ rm -f -- "$GIT_DIR/MERGE_HEAD" &&
+ if test -f "$NEXT_INDEX"
+ then
+ mv "$NEXT_INDEX" "$THIS_INDEX"
+ else
+ : ;# happy
+ fi
else
echo >&2 "* no commit message? aborting commit."
false
@@ -459,8 +644,4 @@ if test -x "$GIT_DIR"/hooks/post-commit && test "$ret" = 0
then
"$GIT_DIR"/hooks/post-commit
fi
-if test 0 -eq "$ret"
-then
- rm -f "$SAVE_INDEX"
-fi
exit "$ret"
diff --git a/git-status.sh b/git-status.sh
deleted file mode 100755
index 10d781c..0000000
--- a/git-status.sh
+++ /dev/null
@@ -1,115 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2005 Linus Torvalds
-#
-
-USAGE=''
-SUBDIRECTORY_OK='Yes'
-
-. git-sh-setup
-
-if [ "$#" != "0" ]
-then
- usage
-fi
-
-report () {
- header="#
-# $1:
-# ($2)
-#
-"
- trailer=""
- while read status name newname
- do
- printf '%s' "$header"
- header=""
- trailer="#
-"
- case "$status" in
- M ) echo "# modified: $name";;
- D*) echo "# deleted: $name";;
- T ) echo "# typechange: $name";;
- C*) echo "# copied: $name -> $newname";;
- R*) echo "# renamed: $name -> $newname";;
- A*) echo "# new file: $name";;
- U ) echo "# unmerged: $name";;
- esac
- done
- printf '%s' "$trailer"
- [ "$header" ]
-}
-
-branch=$(GIT_DIR="$GIT_DIR" git-symbolic-ref HEAD)
-case "$branch" in
-refs/heads/master) ;;
-*) echo "# On branch $branch" ;;
-esac
-
-git-update-index -q --unmerged --refresh || exit
-
-if GIT_DIR="$GIT_DIR" git-rev-parse --verify HEAD >/dev/null 2>&1
-then
- git-diff-index -M --cached --name-status --diff-filter=MDTCRA HEAD |
- sed -e '
- s/\\/\\\\/g
- s/ /\\ /g
- ' |
- report "Updated but not checked in" "will commit"
-
- committable="$?"
-else
- echo '#
-# Initial commit
-#'
- git-ls-files |
- sed -e '
- s/\\/\\\\/g
- s/ /\\ /g
- s/^/A /
- ' |
- report "Updated but not checked in" "will commit"
-
- committable="$?"
-fi
-
-git-diff-files --name-status |
-sed -e '
- s/\\/\\\\/g
- s/ /\\ /g
-' |
-report "Changed but not updated" "use git-update-index to mark for commit"
-
-
-if test -f "$GIT_DIR/info/exclude"
-then
- git-ls-files -z --others --directory \
- --exclude-from="$GIT_DIR/info/exclude" \
- --exclude-per-directory=.gitignore
-else
- git-ls-files -z --others --directory \
- --exclude-per-directory=.gitignore
-fi |
-perl -e '$/ = "\0";
- my $shown = 0;
- while (<>) {
- chomp;
- s|\\|\\\\|g;
- s|\t|\\t|g;
- s|\n|\\n|g;
- s/^/# /;
- if (!$shown) {
- print "#\n# Untracked files:\n";
- print "# (use \"git add\" to add to commit)\n#\n";
- $shown = 1;
- }
- print "$_\n";
- }
-'
-
-case "$committable" in
-0)
- echo "nothing to commit"
- exit 1
-esac
-exit 0
diff --git a/ident.c b/ident.c
index 0461b8b..23b8cfc 100644
--- a/ident.c
+++ b/ident.c
@@ -167,6 +167,11 @@ static const char *get_ident(const char *name, const char *email,
name = git_default_name;
if (!email)
email = git_default_email;
+
+ if (!*name || !*email)
+ die("empty ident %s <%s> not allowed",
+ name, email);
+
strcpy(date, git_default_date);
if (date_str)
parse_date(date_str, date, sizeof(date));
diff --git a/index-pack.c b/index-pack.c
index 541d7bc..babe34b 100644
--- a/index-pack.c
+++ b/index-pack.c
@@ -68,9 +68,9 @@ static void parse_pack_header(void)
hdr = (void *)pack_base;
if (hdr->hdr_signature != htonl(PACK_SIGNATURE))
die("packfile '%s' signature mismatch", pack_name);
- if (hdr->hdr_version != htonl(PACK_VERSION))
- die("packfile '%s' version %d different from ours %d",
- pack_name, ntohl(hdr->hdr_version), PACK_VERSION);
+ if (!pack_version_ok(hdr->hdr_version))
+ die("packfile '%s' version %d unsupported",
+ pack_name, ntohl(hdr->hdr_version));
nr_objects = ntohl(hdr->hdr_entries);
diff --git a/ls-files.c b/ls-files.c
index 6af3b09..7024cf1 100644
--- a/ls-files.c
+++ b/ls-files.c
@@ -474,8 +474,28 @@ static void show_files(void)
const char *path = ".", *base = "";
int baselen = prefix_len;
- if (baselen)
+ if (baselen) {
path = base = prefix;
+ if (exclude_per_dir) {
+ char *p, *pp = xmalloc(baselen+1);
+ memcpy(pp, prefix, baselen+1);
+ p = pp;
+ while (1) {
+ char save = *p;
+ *p = 0;
+ push_exclude_per_directory(pp, p-pp);
+ *p++ = save;
+ if (!save)
+ break;
+ p = strchr(p, '/');
+ if (p)
+ p++;
+ else
+ p = pp + baselen;
+ }
+ free(pp);
+ }
+ }
read_directory(path, base, baselen);
qsort(dir, nr_dir, sizeof(struct nond_on_fs *), cmp_name);
if (show_others)
diff --git a/pack-check.c b/pack-check.c
index 511f294..67a7ecd 100644
--- a/pack-check.c
+++ b/pack-check.c
@@ -16,9 +16,9 @@ static int verify_packfile(struct packed_git *p)
hdr = p->pack_base;
if (hdr->hdr_signature != htonl(PACK_SIGNATURE))
return error("Packfile %s signature mismatch", p->pack_name);
- if (hdr->hdr_version != htonl(PACK_VERSION))
- return error("Packfile version %d different from ours %d",
- ntohl(hdr->hdr_version), PACK_VERSION);
+ if (!pack_version_ok(hdr->hdr_version))
+ return error("Packfile version %d unsupported",
+ ntohl(hdr->hdr_version));
nr_objects = ntohl(hdr->hdr_entries);
if (num_packed_objects(p) != nr_objects)
return error("Packfile claims to have %d objects, "
diff --git a/pack.h b/pack.h
index 657deaa..9dafa2b 100644
--- a/pack.h
+++ b/pack.h
@@ -21,6 +21,7 @@ enum object_type {
*/
#define PACK_SIGNATURE 0x5041434b /* "PACK" */
#define PACK_VERSION 2
+#define pack_version_ok(v) ((v) == htonl(2) || (v) == htonl(3))
struct pack_header {
unsigned int hdr_signature;
unsigned int hdr_version;
diff --git a/patch-delta.c b/patch-delta.c
index 98c27be..c0e1311 100644
--- a/patch-delta.c
+++ b/patch-delta.c
@@ -44,16 +44,15 @@ void *patch_delta(void *src_buf, unsigned long src_size,
cmd = *data++;
if (cmd & 0x80) {
unsigned long cp_off = 0, cp_size = 0;
- const unsigned char *buf;
if (cmd & 0x01) cp_off = *data++;
if (cmd & 0x02) cp_off |= (*data++ << 8);
if (cmd & 0x04) cp_off |= (*data++ << 16);
if (cmd & 0x08) cp_off |= (*data++ << 24);
if (cmd & 0x10) cp_size = *data++;
if (cmd & 0x20) cp_size |= (*data++ << 8);
+ if (cmd & 0x40) cp_size |= (*data++ << 16);
if (cp_size == 0) cp_size = 0x10000;
- buf = (cmd & 0x40) ? dst_buf : src_buf;
- memcpy(out, buf + cp_off, cp_size);
+ memcpy(out, src_buf + cp_off, cp_size);
out += cp_size;
} else {
memcpy(out, data, cmd);
diff --git a/rev-list.c b/rev-list.c
index a554e07..63391fc 100644
--- a/rev-list.c
+++ b/rev-list.c
@@ -32,6 +32,7 @@ static const char rev_list_usage[] =
" --objects\n"
" --unpacked\n"
" --header | --pretty\n"
+" --abbrev=nr | --no-abbrev\n"
" special purpose:\n"
" --bisect"
;
@@ -43,6 +44,7 @@ static int tag_objects = 0;
static int tree_objects = 0;
static int blob_objects = 0;
static int verbose_header = 0;
+static int abbrev = DEFAULT_ABBREV;
static int show_parents = 0;
static int hdr_termination = 0;
static const char *commit_prefix = "";
@@ -96,7 +98,7 @@ static void show_commit(struct commit *commit)
if (verbose_header) {
static char pretty_header[16384];
- pretty_print_commit(commit_format, commit, ~0, pretty_header, sizeof(pretty_header), 0);
+ pretty_print_commit(commit_format, commit, ~0, pretty_header, sizeof(pretty_header), abbrev);
printf("%s%c", pretty_header, hdr_termination);
}
fflush(stdout);
@@ -795,6 +797,18 @@ int main(int argc, const char **argv)
verbose_header = 1;
continue;
}
+ if (!strcmp(arg, "--no-abbrev")) {
+ abbrev = 0;
+ continue;
+ }
+ if (!strncmp(arg, "--abbrev=", 9)) {
+ abbrev = strtoul(arg + 9, NULL, 10);
+ if (abbrev && abbrev < MINIMUM_ABBREV)
+ abbrev = MINIMUM_ABBREV;
+ else if (40 < abbrev)
+ abbrev = 40;
+ continue;
+ }
if (!strncmp(arg, "--pretty", 8)) {
commit_format = get_commit_format(arg+8);
verbose_header = 1;
diff --git a/sha1_file.c b/sha1_file.c
index 20f6419..3d11a9b 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -6,8 +6,6 @@
* This handles basic git sha1 object files - packing, unpacking,
* creation etc.
*/
-#include <sys/types.h>
-#include <dirent.h>
#include "cache.h"
#include "delta.h"
#include "pack.h"
@@ -74,6 +72,8 @@ int adjust_shared_perm(const char *path)
int safe_create_leading_directories(char *path)
{
char *pos = path;
+ struct stat st;
+
if (*pos == '/')
pos++;
@@ -82,12 +82,17 @@ int safe_create_leading_directories(char *path)
if (!pos)
break;
*pos = 0;
- if (mkdir(path, 0777) < 0) {
- if (errno != EEXIST) {
+ if (!stat(path, &st)) {
+ /* path exists */
+ if (!S_ISDIR(st.st_mode)) {
*pos = '/';
- return -1;
+ return -3;
}
}
+ else if (mkdir(path, 0777)) {
+ *pos = '/';
+ return -1;
+ }
else if (adjust_shared_perm(path)) {
*pos = '/';
return -2;
diff --git a/show-branch.c b/show-branch.c
index ffe7456..511fd3b 100644
--- a/show-branch.c
+++ b/show-branch.c
@@ -548,8 +548,8 @@ int main(int ac, char **av)
int with_current_branch = 0;
int head_at = -1;
- git_config(git_show_branch_config);
setup_git_directory();
+ git_config(git_show_branch_config);
/* If nothing is specified, try the default first */
if (ac == 1 && default_num) {
diff --git a/t/t6000lib.sh b/t/t6000lib.sh
index 01f796e..c6752af 100755
--- a/t/t6000lib.sh
+++ b/t/t6000lib.sh
@@ -51,7 +51,12 @@ as_author()
export GIT_AUTHOR_EMAIL="$_author"
"$@"
- export GIT_AUTHOR_EMAIL="$_save"
+ if test -z "$_save"
+ then
+ unset GIT_AUTHOR_EMAIL
+ else
+ export GIT_AUTHOR_EMAIL="$_save"
+ fi
}
commit_date()
diff --git a/unpack-objects.c b/unpack-objects.c
index 4b5b5cb..815a1b3 100644
--- a/unpack-objects.c
+++ b/unpack-objects.c
@@ -246,13 +246,12 @@ static void unpack_all(void)
{
int i;
struct pack_header *hdr = fill(sizeof(struct pack_header));
- unsigned version = ntohl(hdr->hdr_version);
unsigned nr_objects = ntohl(hdr->hdr_entries);
if (ntohl(hdr->hdr_signature) != PACK_SIGNATURE)
die("bad pack file");
- if (version != PACK_VERSION)
- die("unable to handle pack file version %d", version);
+ if (!pack_version_ok(hdr->hdr_version))
+ die("unknown pack file version %d", ntohl(hdr->hdr_version));
fprintf(stderr, "Unpacking %d objects\n", nr_objects);
use(sizeof(struct pack_header));