summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--Documentation/git-rev-parse.txt34
-rw-r--r--Documentation/tutorial.txt35
-rw-r--r--Makefile10
-rw-r--r--README40
-rw-r--r--commit.c2
-rw-r--r--config.c8
-rw-r--r--debian/changelog6
-rw-r--r--fetch-pack.c7
-rwxr-xr-xgit-branch.sh2
-rwxr-xr-xgit-checkout.sh4
-rwxr-xr-xgit-clone.sh15
-rwxr-xr-xgit-commit.sh6
-rwxr-xr-xgit-merge-ours.sh14
-rwxr-xr-xgit-merge.sh30
-rwxr-xr-xgit-pull.sh6
-rw-r--r--ls-files.c2
-rw-r--r--name-rev.c2
-rw-r--r--send-pack.c4
-rw-r--r--server-info.c7
-rw-r--r--sha1_name.c2
-rwxr-xr-xt/t3001-ls-files-others-exclude.sh12
-rw-r--r--tag.c7
-rw-r--r--tag.h2
-rw-r--r--upload-pack.c2
25 files changed, 219 insertions, 41 deletions
diff --git a/.gitignore b/.gitignore
index 927c89c..3edf6b4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -50,6 +50,7 @@ git-merge-base
git-merge-index
git-merge-octopus
git-merge-one-file
+git-merge-ours
git-merge-recursive
git-merge-resolve
git-merge-stupid
diff --git a/Documentation/git-rev-parse.txt b/Documentation/git-rev-parse.txt
index 099db29..431b8f6 100644
--- a/Documentation/git-rev-parse.txt
+++ b/Documentation/git-rev-parse.txt
@@ -72,6 +72,14 @@ OPTIONS
path of the current directory relative to the top-level
directory.
+--since=datestring, --after=datestring::
+ Parses the date string, and outputs corresponding
+ --max-age= parameter for git-rev-list command.
+
+--until=datestring, --before=datestring::
+ Parses the date string, and outputs corresponding
+ --min-age= parameter for git-rev-list command.
+
<args>...::
Flags and parameters to be parsed.
@@ -124,6 +132,32 @@ which is passed to 'git-rev-list'. Two revision parameters
concatenated with '..' is a short-hand for writing a range
between them. I.e. 'r1..r2' is equivalent to saying '{caret}r1 r2'
+Here is an illustration, by Jon Loeliger. Both node B and C are
+a commit parents of commit node A. Parent commits are ordered
+left-to-right.
+
+ G H I J
+ \ / \ /
+ D E F
+ \ | /
+ \ | /
+ \|/
+ B C
+ \ /
+ \ /
+ A
+
+ A = = A^0
+ B = A^ = A^1 = A~1
+ C = A^2 = A^2
+ D = A^^ = A^1^1 = A~2
+ E = B^2 = A^^2
+ F = B^3 = A^^3
+ G = A^^^ = A^1^1^1 = A~3
+ H = D^2 = B^^2 = A^^^2 = A~2^2
+ I = F^ = B^3^ = A^^3^
+ J = F^2 = B^3^2 = A^^3^2
+
Author
------
diff --git a/Documentation/tutorial.txt b/Documentation/tutorial.txt
index 20a4cb1..214673d 100644
--- a/Documentation/tutorial.txt
+++ b/Documentation/tutorial.txt
@@ -455,6 +455,41 @@ the same diff that we've already seen several times, we can now do
(again, `-p` means to show the difference as a human-readable patch),
and it will show what the last commit (in `HEAD`) actually changed.
+[NOTE]
+============
+Here is an ASCII art by Jon Loeliger that illustrates how
+various diff-\* commands compare things.
+
+ diff-tree
+ +----+
+ | |
+ | |
+ V V
+ +-----------+
+ | Object DB |
+ | Backing |
+ | Store |
+ +-----------+
+ ^ ^
+ | |
+ | | diff-index --cached
+ | |
+ diff-index | V
+ | +-----------+
+ | | Index |
+ | | "cache" |
+ | +-----------+
+ | ^
+ | |
+ | | diff-files
+ | |
+ V V
+ +-----------+
+ | Working |
+ | Directory |
+ +-----------+
+============
+
More interestingly, you can also give `git-diff-tree` the `-v` flag, which
tells it to also show the commit message and author and date of the
commit, and you can tell it to show a whole series of diffs.
diff --git a/Makefile b/Makefile
index 5606c83..f96da67 100644
--- a/Makefile
+++ b/Makefile
@@ -52,7 +52,7 @@
# DEFINES += -DUSE_STDEV
-GIT_VERSION = 0.99.9b
+GIT_VERSION = 0.99.9c
CFLAGS = -g -O2 -Wall
ALL_CFLAGS = $(CFLAGS) $(PLATFORM_DEFINES) $(DEFINES)
@@ -89,7 +89,7 @@ SCRIPT_SH = \
git-tag.sh git-verify-tag.sh git-whatchanged.sh git.sh \
git-applymbox.sh git-applypatch.sh git-am.sh \
git-merge.sh git-merge-stupid.sh git-merge-octopus.sh \
- git-merge-resolve.sh git-grep.sh
+ git-merge-resolve.sh git-merge-ours.sh git-grep.sh
SCRIPT_PERL = \
git-archimport.perl git-cvsimport.perl git-relink.perl \
@@ -189,9 +189,9 @@ endif
ifeq ($(uname_S),SunOS)
NEEDS_SOCKET = YesPlease
NEEDS_NSL = YesPlease
+ NEEDS_LIBICONV = YesPlease
SHELL_PATH = /bin/bash
NO_STRCASESTR = YesPlease
- CURLDIR = /opt/sfw
INSTALL = ginstall
TAR = gtar
PLATFORM_DEFINES += -D__EXTENSIONS__
@@ -397,8 +397,8 @@ doc:
test: all
$(MAKE) -C t/ all
-test-date$X: test-date.c date.o
- $(CC) $(ALL_CFLAGS) -o $@ test-date.c date.o
+test-date$X: test-date.c date.o ctype.o
+ $(CC) $(ALL_CFLAGS) -o $@ test-date.c date.o ctype.o
test-delta$X: test-delta.c diff-delta.o patch-delta.o
$(CC) $(ALL_CFLAGS) -o $@ $^
diff --git a/README b/README
index 0ee49d4..4a2616b 100644
--- a/README
+++ b/README
@@ -399,6 +399,46 @@ save the note about that state, in practice we tend to just write the
result to the file `.git/HEAD`, so that we can always see what the
last committed state was.
+Here is an ASCII art by Jon Loeliger that illustrates how
+various pieces fit together.
+
+------------
+
+ commit-tree
+ commit obj
+ +----+
+ | |
+ | |
+ V V
+ +-----------+
+ | Object DB |
+ | Backing |
+ | Store |
+ +-----------+
+ ^
+ write-tree | |
+ tree obj | |
+ | | read-tree
+ | | tree obj
+ V
+ +-----------+
+ | Index |
+ | "cache" |
+ +-----------+
+ update-index ^
+ blob obj | |
+ | |
+ checkout-index -u | | checkout-index
+ stat | | blob obj
+ V
+ +-----------+
+ | Working |
+ | Directory |
+ +-----------+
+
+------------
+
+
6) Examining the data
~~~~~~~~~~~~~~~~~~~~~
diff --git a/commit.c b/commit.c
index 8f40318..a8c9bfc 100644
--- a/commit.c
+++ b/commit.c
@@ -55,7 +55,7 @@ static struct commit *check_commit(struct object *obj,
struct commit *lookup_commit_reference_gently(const unsigned char *sha1,
int quiet)
{
- struct object *obj = deref_tag(parse_object(sha1));
+ struct object *obj = deref_tag(parse_object(sha1), NULL, 0);
if (!obj)
return NULL;
diff --git a/config.c b/config.c
index 519fecf..e89bab2 100644
--- a/config.c
+++ b/config.c
@@ -13,6 +13,14 @@ static int get_next_char(void)
c = '\n';
if ((f = config_file) != NULL) {
c = fgetc(f);
+ if (c == '\r') {
+ /* DOS like systems */
+ c = fgetc(f);
+ if (c != '\n') {
+ ungetc(c, f);
+ c = '\r';
+ }
+ }
if (c == '\n')
config_linenr++;
if (c == EOF) {
diff --git a/debian/changelog b/debian/changelog
index ee68af5..cc97660 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+git-core (0.99.9c-0) unstable; urgency=low
+
+ * GIT 0.99.9c
+
+ -- Junio C Hamano <junkio@cox.net> Thu, 3 Nov 2005 15:44:54 -0800
+
git-core (0.99.9b-0) unstable; urgency=low
* GIT 0.99.9b
diff --git a/fetch-pack.c b/fetch-pack.c
index 3df9911..cb21715 100644
--- a/fetch-pack.c
+++ b/fetch-pack.c
@@ -38,9 +38,9 @@ static void rev_list_push(struct commit *commit, int mark)
static int rev_list_insert_ref(const char *path, const unsigned char *sha1)
{
- struct object *o = deref_tag(parse_object(sha1));
+ struct object *o = deref_tag(parse_object(sha1), path, 0);
- if (o->type == commit_type)
+ if (o && o->type == commit_type)
rev_list_push((struct commit *)o, SEEN);
return 0;
@@ -317,7 +317,8 @@ static int everything_local(struct ref **refs, int nr_match, char **match)
* Don't mark them common yet; the server has to be told so first.
*/
for (ref = *refs; ref; ref = ref->next) {
- struct object *o = deref_tag(lookup_object(ref->old_sha1));
+ struct object *o = deref_tag(lookup_object(ref->old_sha1),
+ NULL, 0);
if (!o || o->type != commit_type || !(o->flags & COMPLETE))
continue;
diff --git a/git-branch.sh b/git-branch.sh
index e2db906..67f113a 100755
--- a/git-branch.sh
+++ b/git-branch.sh
@@ -102,4 +102,6 @@ rev=$(git-rev-parse --verify "$head") || exit
git-check-ref-format "heads/$branchname" ||
die "we do not like '$branchname' as a branch name."
+leading=`expr "refs/heads/$branchname" : '\(.*\)/'` &&
+mkdir -p "$GIT_DIR/$leading" &&
echo $rev > "$GIT_DIR/refs/heads/$branchname"
diff --git a/git-checkout.sh b/git-checkout.sh
index cb33fdc..4c08f36 100755
--- a/git-checkout.sh
+++ b/git-checkout.sh
@@ -126,7 +126,9 @@ fi
#
if [ "$?" -eq 0 ]; then
if [ "$newbranch" ]; then
- echo $new > "$GIT_DIR/refs/heads/$newbranch"
+ leading=`expr "refs/heads/$newbranch" : '\(.*\)/'` &&
+ mkdir -p "$GIT_DIR/$leading" &&
+ echo $new >"$GIT_DIR/refs/heads/$newbranch" || exit
branch="$newbranch"
fi
[ "$branch" ] &&
diff --git a/git-clone.sh b/git-clone.sh
index 18e692a..c27a913 100755
--- a/git-clone.sh
+++ b/git-clone.sh
@@ -196,10 +196,17 @@ cd $D || exit
if test -f ".git/HEAD"
then
- mkdir -p .git/remotes || exit
- echo >.git/remotes/origin \
- "URL: $repo
-Pull: master:origin"
+ head_points_at=`git-symbolic-ref HEAD`
+ case "$head_points_at" in
+ refs/heads/*)
+ head_points_at=`expr "$head_points_at" : 'refs/heads/\(.*\)'`
+ mkdir -p .git/remotes &&
+ echo >.git/remotes/origin \
+ "URL: $repo
+Pull: $head_points_at:origin"
+ cp ".git/refs/heads/$head_points_at" .git/refs/heads/origin
+ esac
+
case "$no_checkout" in
'')
git checkout
diff --git a/git-commit.sh b/git-commit.sh
index 10651d8..daf90f1 100755
--- a/git-commit.sh
+++ b/git-commit.sh
@@ -129,6 +129,9 @@ then
elif test "$use_commit" != ""
then
git-cat-file commit "$use_commit" | sed -e '1,/^$/d'
+elif test -f "$GIT_DIR/MERGE_HEAD" && test -f "$GIT_DIR/MERGE_MSG"
+then
+ cat "$GIT_DIR/MERGE_MSG"
fi | git-stripspace >"$GIT_DIR"/COMMIT_EDITMSG
case "$signoff" in
@@ -144,9 +147,6 @@ t)
esac
if [ -f "$GIT_DIR/MERGE_HEAD" ]; then
-
- test -f "$GIT_DIR/MERGE_MSG" && cat "$GIT_DIR/MERGE_MSG"
-
echo "#"
echo "# It looks like your may be committing a MERGE."
echo "# If this is not correct, please remove the file"
diff --git a/git-merge-ours.sh b/git-merge-ours.sh
new file mode 100755
index 0000000..4f3d053
--- /dev/null
+++ b/git-merge-ours.sh
@@ -0,0 +1,14 @@
+#!/bin/sh
+#
+# Copyright (c) 2005 Junio C Hamano
+#
+# Pretend we resolved the heads, but declare our tree trumps everybody else.
+#
+
+# We need to exit with 2 if the index does not match our HEAD tree,
+# because the current index is what we will be committing as the
+# merge result.
+
+test "$(git-diff-index --cached --name-status HEAD)" = "" || exit 2
+
+exit 0
diff --git a/git-merge.sh b/git-merge.sh
index 6ad96eb..b810fce 100755
--- a/git-merge.sh
+++ b/git-merge.sh
@@ -9,12 +9,12 @@ LF='
'
usage () {
- die "git-merge [-n] [-s <strategy>]... <merge-message> <head> <remote>+"
+ die "git-merge [-n] [--no-commit] [-s <strategy>]... <merge-message> <head> <remote>+"
}
# all_strategies='resolve recursive stupid octopus'
-all_strategies='recursive octopus resolve stupid'
+all_strategies='recursive octopus resolve stupid ours'
default_strategies='resolve octopus'
use_strategies=
@@ -63,6 +63,8 @@ do
-n|--n|--no|--no-|--no-s|--no-su|--no-sum|--no-summ|\
--no-summa|--no-summar|--no-summary)
no_summary=t ;;
+ --no-c|--no-co|--no-com|--no-comm|--no-commi|--no-commit)
+ no_commit=t ;;
-s=*|--s=*|--st=*|--str=*|--stra=*|--strat=*|--strate=*|\
--strateg=*|--strategy=*|\
-s|--s|--st|--str|--stra|--strat|--strate|--strateg|--strategy)
@@ -111,18 +113,18 @@ done
common=$(git-show-branch --merge-base $head "$@")
echo "$head" >"$GIT_DIR/ORIG_HEAD"
-case "$#,$common" in
-*,'')
+case "$#,$common,$no_commit" in
+*,'',*)
# No common ancestors found. We need a real merge.
;;
-1,"$1")
+1,"$1",*)
# If head can reach all the merge then we are up to date.
# but first the most common case of merging one remote
echo "Already up-to-date."
dropsave
exit 0
;;
-1,"$head")
+1,"$head",*)
# Again the most common case of merging one remote.
echo "Updating from $head to $1."
git-update-index --refresh 2>/dev/null
@@ -132,11 +134,11 @@ case "$#,$common" in
dropsave
exit 0
;;
-1,?*"$LF"?*)
+1,?*"$LF"?*,*)
# We are not doing octopus and not fast forward. Need a
# real merge.
;;
-1,*)
+1,*,)
# We are not doing octopus, not fast forward, and have only
# one common. See if it is really trivial.
echo "Trying really trivial in-index merge..."
@@ -210,12 +212,18 @@ do
# Remember which strategy left the state in the working tree
wt_strategy=$strategy
- git-merge-$strategy $common -- "$head_arg" "$@" || {
+ git-merge-$strategy $common -- "$head_arg" "$@"
+ exit=$?
+ if test "$no_commit" = t && test "$exit" = 0
+ then
+ exit=1 ;# pretend it left conflicts.
+ fi
+
+ test "$exit" = 0 || {
# The backend exits with 1 when conflicts are left to be resolved,
# with 2 when it does not handle the given merge at all.
- exit=$?
if test "$exit" -eq 1
then
cnt=`{
@@ -272,4 +280,4 @@ do
done >"$GIT_DIR/MERGE_HEAD"
echo $merge_msg >"$GIT_DIR/MERGE_MSG"
-die "Automatic merge failed; fix up by hand"
+die "Automatic merge failed/prevented; fix up by hand"
diff --git a/git-pull.sh b/git-pull.sh
index d476518..9601627 100755
--- a/git-pull.sh
+++ b/git-pull.sh
@@ -10,13 +10,15 @@ usage () {
die "git pull [-n] [-s strategy]... <repo> <head>..."
}
-strategy_args= no_summary=
+strategy_args= no_summary= no_commit=
while case "$#,$1" in 0) break ;; *,-*) ;; *) break ;; esac
do
case "$1" in
-n|--n|--no|--no-|--no-s|--no-su|--no-sum|--no-summ|\
--no-summa|--no-summar|--no-summary)
no_summary=-n ;;
+ --no-c|--no-co|--no-com|--no-comm|--no-commi|--no-commit)
+ no_commit=--no-commit ;;
-s=*|--s=*|--st=*|--str=*|--stra=*|--strat=*|--strate=*|\
--strateg=*|--strategy=*|\
-s|--s|--st|--str|--stra|--strat|--strate|--strateg|--strategy)
@@ -81,4 +83,4 @@ case "$strategy_args" in
esac
merge_name=$(git-fmt-merge-msg <"$GIT_DIR/FETCH_HEAD")
-git-merge $no_summary $strategy_args "$merge_name" HEAD $merge_head
+git-merge $no_summary $no_commit $strategy_args "$merge_name" HEAD $merge_head
diff --git a/ls-files.c b/ls-files.c
index 3085b2f..d9c8b21 100644
--- a/ls-files.c
+++ b/ls-files.c
@@ -97,7 +97,7 @@ static int add_excludes_from_file_1(const char *fname,
for (i = 0; i < size; i++) {
if (buf[i] == '\n') {
if (entry != buf + i && entry[0] != '#') {
- buf[i] = 0;
+ buf[i - (i && buf[i-1] == '\r')] = 0;
add_exclude(entry, base, baselen, which);
}
entry = buf + i + 1;
diff --git a/name-rev.c b/name-rev.c
index 21fecdf..59194f1 100644
--- a/name-rev.c
+++ b/name-rev.c
@@ -164,7 +164,7 @@ int main(int argc, char **argv)
continue;
}
- o = deref_tag(parse_object(sha1));
+ o = deref_tag(parse_object(sha1), *argv, 0);
if (!o || o->type != commit_type) {
fprintf(stderr, "Could not get commit for %s. Skipping.\n",
*argv);
diff --git a/send-pack.c b/send-pack.c
index 9f9a6e7..3eeb18f 100644
--- a/send-pack.c
+++ b/send-pack.c
@@ -126,12 +126,12 @@ static int ref_newer(const unsigned char *new_sha1,
/* Both new and old must be commit-ish and new is descendant of
* old. Otherwise we require --force.
*/
- o = deref_tag(parse_object(old_sha1));
+ o = deref_tag(parse_object(old_sha1), NULL, 0);
if (!o || o->type != commit_type)
return 0;
old = (struct commit *) o;
- o = deref_tag(parse_object(new_sha1));
+ o = deref_tag(parse_object(new_sha1), NULL, 0);
if (!o || o->type != commit_type)
return 0;
new = (struct commit *) o;
diff --git a/server-info.c b/server-info.c
index ba53591..0cba8e1 100644
--- a/server-info.c
+++ b/server-info.c
@@ -13,9 +13,10 @@ static int add_info_ref(const char *path, const unsigned char *sha1)
fprintf(info_ref_fp, "%s %s\n", sha1_to_hex(sha1), path);
if (o->type == tag_type) {
- o = deref_tag(o);
- fprintf(info_ref_fp, "%s %s^{}\n",
- sha1_to_hex(o->sha1), path);
+ o = deref_tag(o, path, 0);
+ if (o)
+ fprintf(info_ref_fp, "%s %s^{}\n",
+ sha1_to_hex(o->sha1), path);
}
return 0;
}
diff --git a/sha1_name.c b/sha1_name.c
index fe409fb..be1755a 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -349,7 +349,7 @@ static int peel_onion(const char *name, int len, unsigned char *sha1)
if (!o)
return -1;
if (!type_string) {
- o = deref_tag(o);
+ o = deref_tag(o, name, sp - name - 2);
if (!o || (!o->parsed && !parse_object(o->sha1)))
return -1;
memcpy(sha1, o->sha1, 20);
diff --git a/t/t3001-ls-files-others-exclude.sh b/t/t3001-ls-files-others-exclude.sh
index 5beaaa3..fde2bb2 100755
--- a/t/t3001-ls-files-others-exclude.sh
+++ b/t/t3001-ls-files-others-exclude.sh
@@ -67,4 +67,16 @@ test_expect_success \
>output &&
diff -u expect output'
+# Test \r\n (MSDOS-like systems)
+echo -ne '*.1\r\n/*.3\r\n!*.6\r\n' >.gitignore
+
+test_expect_success \
+ 'git-ls-files --others with \r\n line endings.' \
+ 'git-ls-files --others \
+ --exclude=\*.6 \
+ --exclude-per-directory=.gitignore \
+ --exclude-from=.git/ignore \
+ >output &&
+ diff -u expect output'
+
test_done
diff --git a/tag.c b/tag.c
index b1ab75f..e574c4b 100644
--- a/tag.c
+++ b/tag.c
@@ -3,10 +3,15 @@
const char *tag_type = "tag";
-struct object *deref_tag(struct object *o)
+struct object *deref_tag(struct object *o, const char *warn, int warnlen)
{
while (o && o->type == tag_type)
o = parse_object(((struct tag *)o)->tagged->sha1);
+ if (!o && warn) {
+ if (!warnlen)
+ warnlen = strlen(warn);
+ error("missing object referenced by '%.*s'", warnlen, warn);
+ }
return o;
}
diff --git a/tag.h b/tag.h
index 36e5324..7a0cb00 100644
--- a/tag.h
+++ b/tag.h
@@ -15,6 +15,6 @@ struct tag {
extern struct tag *lookup_tag(const unsigned char *sha1);
extern int parse_tag_buffer(struct tag *item, void *data, unsigned long size);
extern int parse_tag(struct tag *item);
-extern struct object *deref_tag(struct object *);
+extern struct object *deref_tag(struct object *, const char *, int);
#endif /* TAG_H */
diff --git a/upload-pack.c b/upload-pack.c
index c5eff21..be63132 100644
--- a/upload-pack.c
+++ b/upload-pack.c
@@ -226,7 +226,7 @@ static int send_ref(const char *refname, const unsigned char *sha1)
nr_our_refs++;
}
if (o->type == tag_type) {
- o = deref_tag(o);
+ o = deref_tag(o, refname, 0);
packet_write(1, "%s %s^{}\n", sha1_to_hex(o->sha1), refname);
}
return 0;