From: Junio C Hamano Date: Wed, 1 Nov 2006 16:48:50 +0000 (-0800) Subject: Merge branch 'lj/refs' X-Git-Tag: v1.4.4-rc1~44 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/58a1e0e83bcdbf063fb708ee9a8a563c0aa14f87?hp=-c Merge branch 'lj/refs' * lj/refs: (63 commits) Fix show-ref usagestring t3200: git-branch testsuite update sha1_name.c: avoid compilation warnings. Make git-branch a builtin ref-log: fix D/F conflict coming from deleted refs. git-revert with conflicts to behave as git-merge with conflicts core.logallrefupdates thinko-fix git-pack-refs --all core.logallrefupdates create new log file only for branch heads. Remove bashism from t3210-pack-refs.sh ref-log: allow ref@{count} syntax. pack-refs: call fflush before fsync. pack-refs: use lockfile as everybody else does. git-fetch: do not look into $GIT_DIR/refs to see if a tag exists. lock_ref_sha1_basic does not remove empty directories on BSD Do not create tag leading directories since git update-ref does it. Check that a tag exists using show-ref instead of looking for the ref file. Use git-update-ref to delete a tag instead of rm()ing the ref file. Fix refs.c;:repack_without_ref() clean-up path Clean up "git-branch.sh" and add remove recursive dir test cases. ... --- 58a1e0e83bcdbf063fb708ee9a8a563c0aa14f87 diff --combined Documentation/config.txt index 026d4cf9ad,232e2a9732..d9e73da2a7 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@@ -71,12 -71,16 +71,16 @@@ core.preferSymlinkRefs: expect HEAD to be a symbolic link. core.logAllRefUpdates:: - If true, `git-update-ref` will append a line to - "$GIT_DIR/logs/" listing the new SHA1 and the date/time - of the update. If the file does not exist it will be - created automatically. This information can be used to - determine what commit was the tip of a branch "2 days ago". - This value is false by default (no logging). + Updates to a ref is logged to the file + "$GIT_DIR/logs/", by appending the new and old + SHA1, the date/time and the reason of the update, but + only when the file exists. If this configuration + variable is set to true, missing "$GIT_DIR/logs/" + file is automatically created for branch heads. + + This information can be used to determine what commit + was the tip of a branch "2 days ago". This value is + false by default (no automated creation of log files). core.repositoryFormatVersion:: Internal variable identifying the repository format and layout @@@ -230,22 -234,6 +234,22 @@@ pull.octopus: pull.twohead:: The default merge strategy to use when pulling a single branch. +remote..url:: + The URL of a remote repository. See gitlink:git-fetch[1] or + gitlink:git-push[1]. + +remote..fetch:: + The default set of "refspec" for gitlink:git-fetch[1]. See + gitlink:git-fetch[1]. + +remote..push:: + The default set of "refspec" for gitlink:git-push[1]. See + gitlink:git-push[1]. + +repack.usedeltabaseoffset:: + Allow gitlink:git-repack[1] to create packs that uses + delta-base offset. Defaults to false. + show.difftree:: The default gitlink:git-diff-tree[1] arguments to be used for gitlink:git-show[1]. diff --combined Makefile index 2d62efb5c4,be8bf392a2..40e2a680f0 --- a/Makefile +++ b/Makefile @@@ -132,8 -132,6 +132,8 @@@ GITWEB_HOMETEXT = indextext.htm GITWEB_CSS = gitweb.css GITWEB_LOGO = git-logo.png GITWEB_FAVICON = git-favicon.png +GITWEB_SITE_HEADER = +GITWEB_SITE_FOOTER = export prefix bindir gitexecdir template_dir GIT_PYTHON_DIR @@@ -158,7 -156,7 +158,7 @@@ BASIC_CFLAGS BASIC_LDFLAGS = SCRIPT_SH = \ - git-bisect.sh git-branch.sh git-checkout.sh \ + git-bisect.sh git-checkout.sh \ git-cherry.sh git-clean.sh git-clone.sh git-commit.sh \ git-fetch.sh \ git-ls-remote.sh \ @@@ -175,7 -173,7 +175,7 @@@ SCRIPT_PERL = \ git-archimport.perl git-cvsimport.perl git-relink.perl \ git-shortlog.perl git-rerere.perl \ - git-annotate.perl git-cvsserver.perl \ + git-cvsserver.perl \ git-svnimport.perl git-cvsexportcommit.perl \ git-send-email.perl git-svn.perl @@@ -267,9 -265,9 +267,10 @@@ LIB_OBJS = BUILTIN_OBJS = \ builtin-add.o \ + builtin-annotate.o \ builtin-apply.o \ builtin-archive.o \ + builtin-branch.o \ builtin-cat-file.o \ builtin-checkout-index.o \ builtin-check-ref-format.o \ @@@ -310,7 -308,9 +311,9 @@@ builtin-update-ref.o \ builtin-upload-archive.o \ builtin-verify-pack.o \ - builtin-write-tree.o + builtin-write-tree.o \ + builtin-show-ref.o \ + builtin-pack-refs.o GITLIBS = $(LIB_FILE) $(XDIFF_LIB) EXTLIBS = -lz @@@ -679,8 -679,6 +682,8 @@@ gitweb/gitweb.cgi: gitweb/gitweb.per -e 's|++GITWEB_CSS++|$(GITWEB_CSS)|g' \ -e 's|++GITWEB_LOGO++|$(GITWEB_LOGO)|g' \ -e 's|++GITWEB_FAVICON++|$(GITWEB_FAVICON)|g' \ + -e 's|++GITWEB_SITE_HEADER++|$(GITWEB_SITE_HEADER)|g' \ + -e 's|++GITWEB_SITE_FOOTER++|$(GITWEB_SITE_FOOTER)|g' \ $< >$@+ chmod +x $@+ mv $@+ $@ @@@ -766,8 -764,6 +769,8 @@@ $(LIB_FILE): $(LIB_OBJS rm -f $@ && $(AR) rcs $@ $(LIB_OBJS) XDIFF_OBJS=xdiff/xdiffi.o xdiff/xprepare.o xdiff/xutils.o xdiff/xemit.o +$(XDIFF_OBJS): xdiff/xinclude.h xdiff/xmacros.h xdiff/xdiff.h xdiff/xtypes.h \ + xdiff/xutils.h xdiff/xprepare.h xdiff/xdiffi.h xdiff/xemit.h $(XDIFF_LIB): $(XDIFF_OBJS) rm -f $@ && $(AR) rcs $@ $(XDIFF_OBJS) @@@ -864,9 -860,8 +867,9 @@@ git.spec: git.spec.i mv $@+ $@ GIT_TARNAME=git-$(GIT_VERSION) -dist: git.spec git-tar-tree - ./git-tar-tree HEAD^{tree} $(GIT_TARNAME) > $(GIT_TARNAME).tar +dist: git.spec git-archive + ./git-archive --format=tar \ + --prefix=$(GIT_TARNAME)/ HEAD^{tree} > $(GIT_TARNAME).tar @mkdir -p $(GIT_TARNAME) @cp git.spec $(GIT_TARNAME) @echo $(GIT_VERSION) > $(GIT_TARNAME)/version diff --combined builtin-prune.c index 7290e6d9aa,e79b515c76..d853902c51 --- a/builtin-prune.c +++ b/builtin-prune.c @@@ -174,7 -174,7 +174,7 @@@ static void walk_commit_list(struct rev } } - static int add_one_ref(const char *path, const unsigned char *sha1) + static int add_one_ref(const char *path, const unsigned char *sha1, int flag, void *cb_data) { struct object *object = parse_object(sha1); if (!object) @@@ -240,7 -240,7 +240,7 @@@ int cmd_prune(int argc, const char **ar revs.tree_objects = 1; /* Add all external refs */ - for_each_ref(add_one_ref); + for_each_ref(add_one_ref, NULL); /* Add all refs from the index file */ add_cache_refs(); @@@ -255,7 -255,5 +255,7 @@@ prune_object_dir(get_object_directory()); + sync(); + prune_packed_objects(show_only); return 0; } diff --combined builtin.h index 708a2f22e8,db9b369e27..f7150aa6b8 --- a/builtin.h +++ b/builtin.h @@@ -11,12 -11,11 +11,13 @@@ extern int mailinfo(FILE *in, FILE *out extern int split_mbox(const char **mbox, const char *dir, int allow_bare, int nr_prec, int skip); extern void stripspace(FILE *in, FILE *out); extern int write_tree(unsigned char *sha1, int missing_ok, const char *prefix); +extern void prune_packed_objects(int); extern int cmd_add(int argc, const char **argv, const char *prefix); +extern int cmd_annotate(int argc, const char **argv, const char *prefix); extern int cmd_apply(int argc, const char **argv, const char *prefix); extern int cmd_archive(int argc, const char **argv, const char *prefix); + extern int cmd_branch(int argc, const char **argv, const char *prefix); extern int cmd_cat_file(int argc, const char **argv, const char *prefix); extern int cmd_checkout_index(int argc, const char **argv, const char *prefix); extern int cmd_check_ref_format(int argc, const char **argv, const char *prefix); @@@ -65,5 -64,7 +66,7 @@@ extern int cmd_version(int argc, const extern int cmd_whatchanged(int argc, const char **argv, const char *prefix); extern int cmd_write_tree(int argc, const char **argv, const char *prefix); extern int cmd_verify_pack(int argc, const char **argv, const char *prefix); + extern int cmd_show_ref(int argc, const char **argv, const char *prefix); + extern int cmd_pack_refs(int argc, const char **argv, const char *prefix); #endif diff --combined cache.h index f4f7be1916,0565333f05..e997a85005 --- a/cache.h +++ b/cache.h @@@ -179,6 -179,7 +179,7 @@@ struct lock_file extern int hold_lock_file_for_update(struct lock_file *, const char *path, int); extern int commit_lock_file(struct lock_file *); extern void rollback_lock_file(struct lock_file *); + extern int delete_ref(const char *, unsigned char *sha1); /* Environment bits from configuration mechanism */ extern int use_legacy_headers; @@@ -188,6 -189,7 +189,6 @@@ extern int prefer_symlink_refs extern int log_all_ref_updates; extern int warn_ambiguous_refs; extern int shared_repository; -extern int deny_non_fast_forwards; extern const char *apply_default_whitespace; extern int zlib_compression_level; @@@ -244,8 -246,13 +245,8 @@@ char *enter_repo(char *path, int strict extern int sha1_object_info(const unsigned char *, char *, unsigned long *); extern void * unpack_sha1_file(void *map, unsigned long mapsize, char *type, unsigned long *size); extern void * read_sha1_file(const unsigned char *sha1, char *type, unsigned long *size); +extern int hash_sha1_file(void *buf, unsigned long len, const char *type, unsigned char *sha1); extern int write_sha1_file(void *buf, unsigned long len, const char *type, unsigned char *return_sha1); -extern char *write_sha1_file_prepare(void *buf, - unsigned long len, - const char *type, - unsigned char *sha1, - unsigned char *hdr, - int *hdrlen); extern int check_sha1_signature(const unsigned char *sha1, void *buf, unsigned long size, const char *type); @@@ -268,9 -275,8 +269,9 @@@ enum object_type OBJ_TREE = 2, OBJ_BLOB = 3, OBJ_TAG = 4, - /* 5/6 for future expansion */ - OBJ_DELTA = 7, + /* 5 for future expansion */ + OBJ_OFS_DELTA = 6, + OBJ_REF_DELTA = 7, OBJ_BAD, }; @@@ -288,9 -294,9 +289,9 @@@ extern int get_sha1(const char *str, un extern int get_sha1_hex(const char *hex, unsigned char *sha1); extern char *sha1_to_hex(const unsigned char *sha1); /* static buffer result! */ extern int read_ref(const char *filename, unsigned char *sha1); - extern const char *resolve_ref(const char *path, unsigned char *sha1, int); - extern int create_symref(const char *git_HEAD, const char *refs_heads_master); - extern int validate_symref(const char *git_HEAD); + extern const char *resolve_ref(const char *path, unsigned char *sha1, int, int *); + extern int create_symref(const char *ref, const char *refs_heads_master); + extern int validate_symref(const char *ref); extern int base_name_compare(const char *name1, int len1, int mode1, const char *name2, int len2, int mode2); extern int cache_name_compare(const char *name1, int len1, const char *name2, int len2); diff --combined fetch-pack.c index 474d54520e,99ac08b2c2..90b79407c6 --- a/fetch-pack.c +++ b/fetch-pack.c @@@ -42,7 -42,7 +42,7 @@@ static void rev_list_push(struct commi } } - static int rev_list_insert_ref(const char *path, const unsigned char *sha1) + static int rev_list_insert_ref(const char *path, const unsigned char *sha1, int flag, void *cb_data) { struct object *o = deref_tag(parse_object(sha1), path, 0); @@@ -143,7 -143,7 +143,7 @@@ static int find_common(int fd[2], unsig unsigned in_vain = 0; int got_continue = 0; - for_each_ref(rev_list_insert_ref); + for_each_ref(rev_list_insert_ref, NULL); fetching = 0; for ( ; refs ; refs = refs->next) { @@@ -166,13 -166,12 +166,13 @@@ } if (!fetching) - packet_write(fd[1], "want %s%s%s%s%s\n", + packet_write(fd[1], "want %s%s%s%s%s%s\n", sha1_to_hex(remote), (multi_ack ? " multi_ack" : ""), (use_sideband == 2 ? " side-band-64k" : ""), (use_sideband == 1 ? " side-band" : ""), - (use_thin_pack ? " thin-pack" : "")); + (use_thin_pack ? " thin-pack" : ""), + " ofs-delta"); else packet_write(fd[1], "want %s\n", sha1_to_hex(remote)); fetching++; @@@ -254,7 -253,7 +254,7 @@@ done static struct commit_list *complete; - static int mark_complete(const char *path, const unsigned char *sha1) + static int mark_complete(const char *path, const unsigned char *sha1, int flag, void *cb_data) { struct object *o = parse_object(sha1); @@@ -366,7 -365,7 +366,7 @@@ static int everything_local(struct ref } } - for_each_ref(mark_complete); + for_each_ref(mark_complete, NULL); if (cutoff) mark_recent_complete_commits(cutoff); diff --combined git-commit.sh index 5b1cf85825,8ac8dcc348..81c3a0cb61 --- a/git-commit.sh +++ b/git-commit.sh @@@ -32,6 -32,33 +32,6 @@@ save_index () cp -p "$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 () { # If TMP_INDEX is defined, that means we are doing # "--only" partial commit, and that index file is used @@@ -41,21 -68,21 +41,21 @@@ # 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 + GIT_INDEX_FILE="$TMP_INDEX" + export GIT_INDEX_FILE elif test -f "$NEXT_INDEX" then - GIT_INDEX_FILE="$NEXT_INDEX" - export GIT_INDEX_FILE + GIT_INDEX_FILE="$NEXT_INDEX" + export GIT_INDEX_FILE fi - case "$status_only" in - t) color= ;; - *) color=--nocolor ;; - esac - git-runstatus ${color} \ - ${verbose:+--verbose} \ - ${amend:+--amend} \ + case "$status_only" in + t) color= ;; + *) color=--nocolor ;; + esac + git-runstatus ${color} \ + ${verbose:+--verbose} \ + ${amend:+--amend} \ ${untracked_files:+--untracked} } @@@ -87,181 -114,179 +87,181 @@@ only_include_assumed untracked_files= while case "$#" in 0) break;; esac do - case "$1" in - -F|--F|-f|--f|--fi|--fil|--file) - case "$#" in 1) usage ;; esac - shift - no_edit=t - log_given=t$log_given - logfile="$1" - shift - ;; - -F*|-f*) - no_edit=t - log_given=t$log_given - logfile=`expr "z$1" : 'z-[Ff]\(.*\)'` - shift - ;; - --F=*|--f=*|--fi=*|--fil=*|--file=*) - no_edit=t - log_given=t$log_given - logfile=`expr "z$1" : 'z-[^=]*=\(.*\)'` - shift - ;; - -a|--a|--al|--all) - all=t - shift - ;; - --au=*|--aut=*|--auth=*|--autho=*|--author=*) - force_author=`expr "z$1" : 'z-[^=]*=\(.*\)'` - shift - ;; - --au|--aut|--auth|--autho|--author) - case "$#" in 1) usage ;; esac - shift - force_author="$1" - shift - ;; - -e|--e|--ed|--edi|--edit) - edit_flag=t - shift - ;; - -i|--i|--in|--inc|--incl|--inclu|--includ|--include) - also=t - shift - ;; - -o|--o|--on|--onl|--only) - only=t - shift - ;; - -m|--m|--me|--mes|--mess|--messa|--messag|--message) - case "$#" in 1) usage ;; esac - shift - log_given=m$log_given - if test "$log_message" = '' - then - log_message="$1" - else - log_message="$log_message + case "$1" in + -F|--F|-f|--f|--fi|--fil|--file) + case "$#" in 1) usage ;; esac + shift + no_edit=t + log_given=t$log_given + logfile="$1" + shift + ;; + -F*|-f*) + no_edit=t + log_given=t$log_given + logfile=`expr "z$1" : 'z-[Ff]\(.*\)'` + shift + ;; + --F=*|--f=*|--fi=*|--fil=*|--file=*) + no_edit=t + log_given=t$log_given + logfile=`expr "z$1" : 'z-[^=]*=\(.*\)'` + shift + ;; + -a|--a|--al|--all) + all=t + shift + ;; + --au=*|--aut=*|--auth=*|--autho=*|--author=*) + force_author=`expr "z$1" : 'z-[^=]*=\(.*\)'` + shift + ;; + --au|--aut|--auth|--autho|--author) + case "$#" in 1) usage ;; esac + shift + force_author="$1" + shift + ;; + -e|--e|--ed|--edi|--edit) + edit_flag=t + shift + ;; + -i|--i|--in|--inc|--incl|--inclu|--includ|--include) + also=t + shift + ;; + -o|--o|--on|--onl|--only) + only=t + shift + ;; + -m|--m|--me|--mes|--mess|--messa|--messag|--message) + case "$#" in 1) usage ;; esac + shift + log_given=m$log_given + if test "$log_message" = '' + then + log_message="$1" + else + log_message="$log_message $1" - fi - no_edit=t - shift - ;; - -m*) - log_given=m$log_given - if test "$log_message" = '' - then - log_message=`expr "z$1" : 'z-m\(.*\)'` - else - log_message="$log_message + fi + no_edit=t + shift + ;; + -m*) + log_given=m$log_given + if test "$log_message" = '' + then + log_message=`expr "z$1" : 'z-m\(.*\)'` + else + log_message="$log_message `expr "z$1" : 'z-m\(.*\)'`" - fi - no_edit=t - shift - ;; - --m=*|--me=*|--mes=*|--mess=*|--messa=*|--messag=*|--message=*) - log_given=m$log_given - if test "$log_message" = '' - then - log_message=`expr "z$1" : 'z-[^=]*=\(.*\)'` - else - log_message="$log_message + fi + no_edit=t + shift + ;; + --m=*|--me=*|--mes=*|--mess=*|--messa=*|--messag=*|--message=*) + log_given=m$log_given + if test "$log_message" = '' + then + log_message=`expr "z$1" : 'z-[^=]*=\(.*\)'` + else + log_message="$log_message `expr "z$1" : 'zq-[^=]*=\(.*\)'`" - fi - no_edit=t - shift - ;; - -n|--n|--no|--no-|--no-v|--no-ve|--no-ver|--no-veri|--no-verif|--no-verify) - verify= - shift - ;; - --a|--am|--ame|--amen|--amend) - amend=t - log_given=t$log_given - use_commit=HEAD - shift - ;; - -c) - case "$#" in 1) usage ;; esac - shift - log_given=t$log_given - use_commit="$1" - no_edit= - shift - ;; - --ree=*|--reed=*|--reedi=*|--reedit=*|--reedit-=*|--reedit-m=*|\ - --reedit-me=*|--reedit-mes=*|--reedit-mess=*|--reedit-messa=*|\ - --reedit-messag=*|--reedit-message=*) - log_given=t$log_given - use_commit=`expr "z$1" : 'z-[^=]*=\(.*\)'` - no_edit= - shift - ;; - --ree|--reed|--reedi|--reedit|--reedit-|--reedit-m|--reedit-me|\ - --reedit-mes|--reedit-mess|--reedit-messa|--reedit-messag|--reedit-message) - case "$#" in 1) usage ;; esac - shift - log_given=t$log_given - use_commit="$1" - no_edit= - shift - ;; - -C) - case "$#" in 1) usage ;; esac - shift - log_given=t$log_given - use_commit="$1" - no_edit=t - shift - ;; - --reu=*|--reus=*|--reuse=*|--reuse-=*|--reuse-m=*|--reuse-me=*|\ - --reuse-mes=*|--reuse-mess=*|--reuse-messa=*|--reuse-messag=*|\ - --reuse-message=*) - log_given=t$log_given - use_commit=`expr "z$1" : 'z-[^=]*=\(.*\)'` - no_edit=t - shift - ;; - --reu|--reus|--reuse|--reuse-|--reuse-m|--reuse-me|--reuse-mes|\ - --reuse-mess|--reuse-messa|--reuse-messag|--reuse-message) - case "$#" in 1) usage ;; esac - shift - log_given=t$log_given - use_commit="$1" - no_edit=t - shift - ;; - -s|--s|--si|--sig|--sign|--signo|--signof|--signoff) - signoff=t - shift - ;; - -v|--v|--ve|--ver|--verb|--verbo|--verbos|--verbose) - verbose=t - shift - ;; - -u|--u|--un|--unt|--untr|--untra|--untrac|--untrack|--untracke|--untracked|\ - --untracked-|--untracked-f|--untracked-fi|--untracked-fil|--untracked-file|\ - --untracked-files) - untracked_files=t - shift - ;; - --) - shift - break - ;; - -*) - usage - ;; - *) - break - ;; - esac + fi + no_edit=t + shift + ;; + -n|--n|--no|--no-|--no-v|--no-ve|--no-ver|--no-veri|--no-verif|\ + --no-verify) + verify= + shift + ;; + --a|--am|--ame|--amen|--amend) + amend=t + log_given=t$log_given + use_commit=HEAD + shift + ;; + -c) + case "$#" in 1) usage ;; esac + shift + log_given=t$log_given + use_commit="$1" + no_edit= + shift + ;; + --ree=*|--reed=*|--reedi=*|--reedit=*|--reedit-=*|--reedit-m=*|\ + --reedit-me=*|--reedit-mes=*|--reedit-mess=*|--reedit-messa=*|\ + --reedit-messag=*|--reedit-message=*) + log_given=t$log_given + use_commit=`expr "z$1" : 'z-[^=]*=\(.*\)'` + no_edit= + shift + ;; + --ree|--reed|--reedi|--reedit|--reedit-|--reedit-m|--reedit-me|\ + --reedit-mes|--reedit-mess|--reedit-messa|--reedit-messag|\ + --reedit-message) + case "$#" in 1) usage ;; esac + shift + log_given=t$log_given + use_commit="$1" + no_edit= + shift + ;; + -C) + case "$#" in 1) usage ;; esac + shift + log_given=t$log_given + use_commit="$1" + no_edit=t + shift + ;; + --reu=*|--reus=*|--reuse=*|--reuse-=*|--reuse-m=*|--reuse-me=*|\ + --reuse-mes=*|--reuse-mess=*|--reuse-messa=*|--reuse-messag=*|\ + --reuse-message=*) + log_given=t$log_given + use_commit=`expr "z$1" : 'z-[^=]*=\(.*\)'` + no_edit=t + shift + ;; + --reu|--reus|--reuse|--reuse-|--reuse-m|--reuse-me|--reuse-mes|\ + --reuse-mess|--reuse-messa|--reuse-messag|--reuse-message) + case "$#" in 1) usage ;; esac + shift + log_given=t$log_given + use_commit="$1" + no_edit=t + shift + ;; + -s|--s|--si|--sig|--sign|--signo|--signof|--signoff) + signoff=t + shift + ;; + -v|--v|--ve|--ver|--verb|--verbo|--verbos|--verbose) + verbose=t + shift + ;; + -u|--u|--un|--unt|--untr|--untra|--untrac|--untrack|--untracke|\ + --untracked|--untracked-|--untracked-f|--untracked-fi|--untracked-fil|\ + --untracked-file|--untracked-files) + untracked_files=t + shift + ;; + --) + shift + break + ;; + -*) + usage + ;; + *) + break + ;; + esac done case "$edit_flag" in t) no_edit= ;; esac @@@ -270,33 -295,33 +270,33 @@@ case "$amend,$initial_commit" in t,t) - die "You do not have anything to amend." ;; + die "You do not have anything to amend." ;; t,) - if [ -f "$GIT_DIR/MERGE_HEAD" ]; then - die "You are in the middle of a merge -- cannot amend." - fi ;; + if [ -f "$GIT_DIR/MERGE_HEAD" ]; then + die "You are in the middle of a merge -- cannot amend." + fi ;; esac case "$log_given" in tt*) - die "Only one of -c/-C/-F can be used." ;; + die "Only one of -c/-C/-F can be used." ;; *tm*|*mt*) - die "Option -m cannot be combined with -c/-C/-F." ;; + die "Option -m cannot be combined with -c/-C/-F." ;; esac case "$#,$also,$only,$amend" in *,t,t,*) - die "Only one of --include/--only can be used." ;; + die "Only one of --include/--only can be used." ;; 0,t,,* | 0,,t,) - die "No paths with --include/--only does not make sense." ;; + die "No paths with --include/--only does not make sense." ;; 0,,t,t) - only_include_assumed="# Clever... amending the last one with dirty index." ;; + only_include_assumed="# Clever... amending the last one with dirty index." ;; 0,,,*) - ;; + ;; *,,,*) - only_include_assumed="# Explicit paths specified without -i nor -o; assuming --only paths..." - also= - ;; + only_include_assumed="# Explicit paths specified without -i nor -o; assuming --only paths..." + also= + ;; esac unset only case "$all,$also,$#" in @@@ -343,47 -368,47 +343,47 @@@ t, ,) case "$#" in 0) - ;; # commit as-is + ;; # commit as-is *) - if test -f "$GIT_DIR/MERGE_HEAD" - then - refuse_partial "Cannot do a partial commit during a merge." - fi - TMP_INDEX="$GIT_DIR/tmp-index$$" - if test -z "$initial_commit" - then - # make sure index is clean at the specified paths, or - # they are additions. - dirty_in_index=`git-diff-index --cached --name-status \ - --diff-filter=DMTU HEAD -- "$@"` - test -z "$dirty_in_index" || - refuse_partial "Different in index and the last commit: + if test -f "$GIT_DIR/MERGE_HEAD" + then + refuse_partial "Cannot do a partial commit during a merge." + fi + TMP_INDEX="$GIT_DIR/tmp-index$$" + if test -z "$initial_commit" + then + # make sure index is clean at the specified paths, or + # they are additions. + dirty_in_index=`git-diff-index --cached --name-status \ + --diff-filter=DMTU HEAD -- "$@"` + test -z "$dirty_in_index" || + refuse_partial "Different in index and the last commit: $dirty_in_index" - fi - commit_only=`git-ls-files --error-unmatch -- "$@"` || exit + fi + commit_only=`git-ls-files --error-unmatch -- "$@"` || exit - # 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 + # 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 && + 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 - ;; + save_index && + echo "$commit_only" | + ( + GIT_INDEX_FILE="$NEXT_INDEX" + export GIT_INDEX_FILE + git-update-index --remove --stdin + ) || exit + ;; esac ;; esac @@@ -401,7 -426,7 +401,7 @@@ els fi GIT_INDEX_FILE="$USE_INDEX" \ - git-update-index -q $unmerged_ok_if_status --refresh || exit + git-update-index -q $unmerged_ok_if_status --refresh || exit ################################################################ # If the request is status, just show it and exit. @@@ -441,7 -466,7 +441,7 @@@ the 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" + elif test -f "$GIT_DIR/MERGE_MSG" then cat "$GIT_DIR/MERGE_MSG" elif test -f "$GIT_DIR/SQUASH_MSG" @@@ -522,15 -547,15 +522,15 @@@ the PARENTS=$(git-cat-file commit HEAD | sed -n -e '/^$/q' -e 's/^parent /-p /p') fi - current=$(git-rev-parse --verify HEAD) + current="$(git-rev-parse --verify HEAD)" else if [ -z "$(git-ls-files)" ]; then echo >&2 Nothing to commit exit 1 fi PARENTS="" - current= rloga='commit (initial)' + current='' fi if test -z "$no_edit" @@@ -606,8 -631,8 +606,8 @@@ the fi && commit=$(cat "$GIT_DIR"/COMMIT_MSG | git-commit-tree $tree $PARENTS) && rlogm=$(sed -e 1q "$GIT_DIR"/COMMIT_MSG) && - git-update-ref -m "$rloga: $rlogm" HEAD $commit $current && - rm -f -- "$GIT_DIR/MERGE_HEAD" && + git-update-ref -m "$rloga: $rlogm" HEAD $commit "$current" && + rm -f -- "$GIT_DIR/MERGE_HEAD" "$GIT_DIR/MERGE_MSG" && if test -f "$NEXT_INDEX" then mv "$NEXT_INDEX" "$THIS_INDEX" diff --combined git-fetch.sh index 7dc1f33687,e8a7668182..fa73ad2260 --- a/git-fetch.sh +++ b/git-fetch.sh @@@ -129,25 -129,22 +129,25 @@@ append_fetch_head () then headc_=$(git-rev-parse --verify "$head_^0") || exit echo "$headc_ $not_for_merge_ $note_" >>"$GIT_DIR/FETCH_HEAD" - [ "$verbose" ] && echo >&2 "* committish: $head_" - [ "$verbose" ] && echo >&2 " $note_" else echo "$head_ not-for-merge $note_" >>"$GIT_DIR/FETCH_HEAD" - [ "$verbose" ] && echo >&2 "* non-commit: $head_" - [ "$verbose" ] && echo >&2 " $note_" - fi - if test "$local_name_" != "" - then - # We are storing the head locally. Make sure that it is - # a fast forward (aka "reverse push"). - fast_forward_local "$local_name_" "$head_" "$note_" fi + + update_local_ref "$local_name_" "$head_" "$note_" } -fast_forward_local () { +update_local_ref () { + # If we are storing the head locally make sure that it is + # a fast forward (aka "reverse push"). + + label_=$(git-cat-file -t $2) + newshort_=$(git-rev-parse --short $2) + if test -z "$1" ; then + [ "$verbose" ] && echo >&2 "* fetched $3" + [ "$verbose" ] && echo >&2 " $label_: $newshort_" + return 0 + fi + oldshort_=$(git-rev-parse --short "$1" 2>/dev/null) mkdir -p "$(dirname "$GIT_DIR/$1")" case "$1" in refs/tags/*) @@@ -157,16 -154,13 +157,16 @@@ then if now_=$(cat "$GIT_DIR/$1") && test "$now_" = "$2" then - [ "$verbose" ] && echo >&2 "* $1: same as $3" ||: + [ "$verbose" ] && echo >&2 "* $1: same as $3" + [ "$verbose" ] && echo >&2 " $label_: $newshort_" ||: else echo >&2 "* $1: updating with $3" + echo >&2 " $label_: $newshort_" git-update-ref -m "$rloga: updating tag" "$1" "$2" fi else echo >&2 "* $1: storing $3" + echo >&2 " $label_: $newshort_" git-update-ref -m "$rloga: storing tag" "$1" "$2" fi ;; @@@ -184,34 -178,31 +184,34 @@@ if test -n "$verbose" then echo >&2 "* $1: same as $3" + echo >&2 " $label_: $newshort_" fi ;; *,$local) echo >&2 "* $1: fast forward to $3" - echo >&2 " from $local to $2" + echo >&2 " old..new: $oldshort_..$newshort_" git-update-ref -m "$rloga: fast-forward" "$1" "$2" "$local" ;; *) false ;; esac || { - echo >&2 "* $1: does not fast forward to $3;" case ",$force,$single_force," in *,t,*) - echo >&2 " forcing update." + echo >&2 "* $1: forcing update to non-fast forward $3" + echo >&2 " old...new: $oldshort_...$newshort_" git-update-ref -m "$rloga: forced-update" "$1" "$2" "$local" ;; *) - echo >&2 " not updating." + echo >&2 "* $1: not updating to non-fast forward $3" + echo >&2 " old...new: $oldshort_...$newshort_" exit 1 ;; esac } else echo >&2 "* $1: storing $3" + echo >&2 " $label_: $newshort_" git-update-ref -m "$rloga: storing head" "$1" "$2" fi ;; @@@ -296,7 -287,6 +296,7 @@@ fetch_main () # There are transports that can fetch only one head at a time... case "$remote" in http://* | https://* | ftp://*) + proto=`expr "$remote" : '\([^:]*\):'` if [ -n "$GIT_SSL_NO_VERIFY" ]; then curl_extra_args="-k" fi @@@ -320,7 -310,7 +320,7 @@@ done expr "z$head" : "z$_x40\$" >/dev/null || die "Failed to fetch $remote_name from $remote" - echo >&2 Fetching "$remote_name from $remote" using http + echo >&2 "Fetching $remote_name from $remote using $proto" git-http-fetch -v -a "$head" "$remote/" || exit ;; rsync://*) @@@ -427,7 -417,7 +427,7 @@@ case "$no_tags$tags" i sed -ne 's|^\([0-9a-f]*\)[ ]\(refs/tags/.*\)^{}$|\1 \2|p' | while read sha1 name do - test -f "$GIT_DIR/$name" && continue + git-show-ref --verify --quiet -- $name && continue git-check-ref-format "$name" || { echo >&2 "warning: tag ${name} ignored" continue @@@ -446,10 -436,10 +446,10 @@@ esa # If the original head was empty (i.e. no "master" yet), or # if we were told not to worry, we do not have to check. -case ",$update_head_ok,$orig_head," in -*,, | t,* ) +case "$orig_head" in +'') ;; -*) +?*) curr_head=$(git-rev-parse --verify HEAD 2>/dev/null) if test "$curr_head" != "$orig_head" then diff --combined git-revert.sh index 4fd81b6ed6,066e67753e..6eab3c72df --- a/git-revert.sh +++ b/git-revert.sh @@@ -7,20 -7,18 +7,20 @@@ case "$0" in *-revert* ) test -t 0 && edit=-e + replay= me=revert USAGE='[--edit | --no-edit] [-n] ' ;; *-cherry-pick* ) + replay=t edit= me=cherry-pick - USAGE='[--edit] [-n] [-r] ' ;; + USAGE='[--edit] [-n] [-r] [-x] ' ;; * ) die "What are you talking about?" ;; esac . git-sh-setup -no_commit= replay= +no_commit= while case "$#" in 0) break ;; esac do case "$1" in @@@ -34,10 -32,8 +34,10 @@@ --n|--no|--no-|--no-e|--no-ed|--no-edi|--no-edit) edit= ;; - -r|--r|--re|--rep|--repl|--repla|--replay) - replay=t + -r) + : no-op ;; + -x|--i-really-want-to-expose-my-private-commit-object-name) + replay= ;; -*) usage @@@ -125,7 -121,7 +125,7 @@@ cherry-pick git-cat-file commit $commit | sed -e '1,/^$/d' case "$replay" in '') - echo "(cherry picked from $commit commit)" + echo "(cherry picked from commit $commit)" test "$rev" = "$commit" || echo "(original 'git cherry-pick' arguments: $@)" ;; @@@ -145,9 -141,18 +145,18 @@@ git-read-tree -m -u --aggressive $base result=$(git-write-tree 2>/dev/null) || { echo >&2 "Simple $me fails; trying Automatic $me." git-merge-index -o git-merge-one-file -a || { + mv -f .msg "$GIT_DIR/MERGE_MSG" + { + echo ' + Conflicts: + ' + git ls-files --unmerged | + sed -e 's/^[^ ]* / /' | + uniq + } >>"$GIT_DIR/MERGE_MSG" echo >&2 "Automatic $me failed. After resolving the conflicts," echo >&2 "mark the corrected paths with 'git-update-index '" - echo >&2 "and commit with 'git commit -F .msg'" + echo >&2 "and commit the result." case "$me" in cherry-pick) echo >&2 "You may choose to use the following when making" diff --combined git.c index 6475847b7a,f197169df2..af181d93b1 --- a/git.c +++ b/git.c @@@ -16,7 -16,7 +16,7 @@@ #include "builtin.h" const char git_usage_string[] = - "git [--version] [--exec-path[=GIT_EXEC_PATH]] [--help] COMMAND [ ARGS ]"; + "git [--version] [--exec-path[=GIT_EXEC_PATH]] [-p|--paginate] [--bare] [--git-dir=GIT_DIR] [--help] COMMAND [ARGS]"; static void prepend_to_path(const char *dir, int len) { @@@ -219,15 -219,15 +219,16 @@@ static void handle_internal_command(in int option; } commands[] = { { "add", cmd_add, RUN_SETUP }, + { "annotate", cmd_annotate, }, { "apply", cmd_apply }, { "archive", cmd_archive }, + { "branch", cmd_branch }, { "cat-file", cmd_cat_file, RUN_SETUP }, { "checkout-index", cmd_checkout_index, RUN_SETUP }, { "check-ref-format", cmd_check_ref_format }, { "commit-tree", cmd_commit_tree, RUN_SETUP }, { "count-objects", cmd_count_objects, RUN_SETUP }, - { "diff", cmd_diff, RUN_SETUP }, + { "diff", cmd_diff, RUN_SETUP | USE_PAGER }, { "diff-files", cmd_diff_files, RUN_SETUP }, { "diff-index", cmd_diff_index, RUN_SETUP }, { "diff-stages", cmd_diff_stages, RUN_SETUP }, @@@ -260,7 -260,7 +261,7 @@@ { "show", cmd_show, RUN_SETUP | USE_PAGER }, { "stripspace", cmd_stripspace }, { "symbolic-ref", cmd_symbolic_ref, RUN_SETUP }, - { "tar-tree", cmd_tar_tree, RUN_SETUP }, + { "tar-tree", cmd_tar_tree }, { "unpack-objects", cmd_unpack_objects, RUN_SETUP }, { "update-index", cmd_update_index, RUN_SETUP }, { "update-ref", cmd_update_ref, RUN_SETUP }, @@@ -269,6 -269,8 +270,8 @@@ { "whatchanged", cmd_whatchanged, RUN_SETUP | USE_PAGER }, { "write-tree", cmd_write_tree, RUN_SETUP }, { "verify-pack", cmd_verify_pack }, + { "show-ref", cmd_show_ref, RUN_SETUP }, + { "pack-refs", cmd_pack_refs, RUN_SETUP }, }; int i; diff --combined receive-pack.c index f2b1c29bd7,1fcf3a9112..de1d6a4b1c --- a/receive-pack.c +++ b/receive-pack.c @@@ -9,26 -9,12 +9,26 @@@ static const char receive_pack_usage[] static const char *unpacker[] = { "unpack-objects", NULL }; +static int deny_non_fast_forwards = 0; static int report_status; static char capabilities[] = "report-status"; static int capabilities_sent; +static int receive_pack_config(const char *var, const char *value) +{ + git_default_config(var, value); + + if (strcmp(var, "receive.denynonfastforwards") == 0) + { + deny_non_fast_forwards = git_config_bool(var, value); + return 0; + } + + return 0; +} + - static int show_ref(const char *path, const unsigned char *sha1) + static int show_ref(const char *path, const unsigned char *sha1, int flag, void *cb_data) { if (capabilities_sent) packet_write(1, "%s %s\n", sha1_to_hex(sha1), path); @@@ -41,9 -27,9 +41,9 @@@ static void write_head_info(void) { - for_each_ref(show_ref); + for_each_ref(show_ref, NULL); if (!capabilities_sent) - show_ref("capabilities^{}", null_sha1); + show_ref("capabilities^{}", null_sha1, 0, NULL); } @@@ -57,34 -43,6 +57,6 @@@ struct command static struct command *commands; - static int is_all_zeroes(const char *hex) - { - int i; - for (i = 0; i < 40; i++) - if (*hex++ != '0') - return 0; - return 1; - } - - static int verify_old_ref(const char *name, char *hex_contents) - { - int fd, ret; - char buffer[60]; - - if (is_all_zeroes(hex_contents)) - return 0; - fd = open(name, O_RDONLY); - if (fd < 0) - return -1; - ret = read(fd, buffer, 40); - close(fd); - if (ret != 40) - return -1; - if (memcmp(buffer, hex_contents, 40)) - return -1; - return 0; - } - static char update_hook[] = "hooks/update"; static int run_update_hook(const char *refname, @@@ -121,8 -79,8 +93,8 @@@ static int update(struct command *cmd const char *name = cmd->ref_name; unsigned char *old_sha1 = cmd->old_sha1; unsigned char *new_sha1 = cmd->new_sha1; - char new_hex[60], *old_hex, *lock_name; - int newfd, namelen, written; + char new_hex[41], old_hex[41]; + struct ref_lock *lock; cmd->error_string = NULL; if (!strncmp(name, "refs/", 5) && check_ref_format(name + 5)) { @@@ -131,13 -89,8 +103,8 @@@ name); } - namelen = strlen(name); - lock_name = xmalloc(namelen + 10); - memcpy(lock_name, name, namelen); - memcpy(lock_name + namelen, ".lock", 6); - strcpy(new_hex, sha1_to_hex(new_sha1)); - old_hex = sha1_to_hex(old_sha1); + strcpy(old_hex, sha1_to_hex(old_sha1)); if (!has_sha1_file(new_sha1)) { cmd->error_string = "bad pack"; return error("unpack should have generated %s, " @@@ -158,47 -111,20 +125,20 @@@ return error("denying non-fast forward;" " you should pull first"); } - safe_create_leading_directories(lock_name); - - newfd = open(lock_name, O_CREAT | O_EXCL | O_WRONLY, 0666); - if (newfd < 0) { - cmd->error_string = "can't lock"; - return error("unable to create %s (%s)", - lock_name, strerror(errno)); - } - - /* Write the ref with an ending '\n' */ - new_hex[40] = '\n'; - new_hex[41] = 0; - written = write(newfd, new_hex, 41); - /* Remove the '\n' again */ - new_hex[40] = 0; - - close(newfd); - if (written != 41) { - unlink(lock_name); - cmd->error_string = "can't write"; - return error("unable to write %s", lock_name); - } - if (verify_old_ref(name, old_hex) < 0) { - unlink(lock_name); - cmd->error_string = "raced"; - return error("%s changed during push", name); - } if (run_update_hook(name, old_hex, new_hex)) { - unlink(lock_name); cmd->error_string = "hook declined"; return error("hook declined to update %s", name); } - else if (rename(lock_name, name) < 0) { - unlink(lock_name); - cmd->error_string = "can't rename"; - return error("unable to replace %s", name); - } - else { - fprintf(stderr, "%s: %s -> %s\n", name, old_hex, new_hex); - return 0; + + lock = lock_any_ref_for_update(name, old_sha1); + if (!lock) { + cmd->error_string = "failed to lock"; + return error("failed to lock %s", name); } + write_ref_sha1(lock, new_sha1, "push"); + + fprintf(stderr, "%s: %s -> %s\n", name, old_hex, new_hex); + return 0; } static char update_post_hook[] = "hooks/post-update"; @@@ -349,10 -275,11 +289,11 @@@ int main(int argc, char **argv if (!dir) usage(receive_pack_usage); - if(!enter_repo(dir, 0)) + if (!enter_repo(dir, 0)) die("'%s': unable to chdir or not a git archive", dir); + setup_ident(); - git_config(git_default_config); + git_config(receive_pack_config); write_head_info(); diff --combined revision.c index 04fa7e5171,d87cb6cd64..3dbc26c49c --- a/revision.c +++ b/revision.c @@@ -418,6 -418,9 +418,6 @@@ static void limit_list(struct rev_info if (revs->max_age != -1 && (commit->date < revs->max_age)) obj->flags |= UNINTERESTING; - if (revs->unpacked && - has_sha1_pack(obj->sha1, revs->ignore_packed)) - obj->flags |= UNINTERESTING; add_parents_to_list(revs, commit, &list); if (obj->flags & UNINTERESTING) { mark_parents_uninteresting(commit); @@@ -465,7 -468,7 +465,7 @@@ static int all_flags; static struct rev_info *all_revs; - static int handle_one_ref(const char *path, const unsigned char *sha1) + static int handle_one_ref(const char *path, const unsigned char *sha1, int flag, void *cb_data) { struct object *object = get_reference(all_revs, path, sha1, all_flags); add_pending_object(all_revs, object, ""); @@@ -476,7 -479,7 +476,7 @@@ static void handle_all(struct rev_info { all_revs = revs; all_flags = flags; - for_each_ref(handle_one_ref); + for_each_ref(handle_one_ref, NULL); } static int add_parents_only(struct rev_info *revs, const char *arg, int flags) @@@ -729,7 -732,6 +729,7 @@@ int setup_revisions(int argc, const cha int i, flags, seen_dashdash, show_merge; const char **unrecognized = argv + 1; int left = 1; + int all_match = 0; /* First, search for "--" */ seen_dashdash = 0; @@@ -965,10 -967,6 +965,10 @@@ add_message_grep(revs, arg+7); continue; } + if (!strcmp(arg, "--all-match")) { + all_match = 1; + continue; + } opts = diff_opt_parse(&revs->diffopt, argv+i, argc-i); if (opts > 0) { @@@ -1012,7 -1010,7 +1012,7 @@@ add_pending_object(revs, object, def); } - if (revs->topo_order || revs->unpacked) + if (revs->topo_order) revs->limited = 1; if (revs->prune_data) { @@@ -1030,10 -1028,8 +1030,10 @@@ if (diff_setup_done(&revs->diffopt) < 0) die("diff_setup_done failed"); - if (revs->grep_filter) + if (revs->grep_filter) { + revs->grep_filter->all_match = all_match; compile_grep_patterns(revs->grep_filter); + } return left; } @@@ -1146,18 -1142,17 +1146,18 @@@ struct commit *get_revision(struct rev_ * that we'd otherwise have done in limit_list(). */ if (!revs->limited) { - if ((revs->unpacked && - has_sha1_pack(commit->object.sha1, - revs->ignore_packed)) || - (revs->max_age != -1 && - (commit->date < revs->max_age))) + if (revs->max_age != -1 && + (commit->date < revs->max_age)) continue; add_parents_to_list(revs, commit, &revs->commits); } if (commit->object.flags & SHOWN) continue; + if (revs->unpacked && has_sha1_pack(commit->object.sha1, + revs->ignore_packed)) + continue; + /* We want to show boundary commits only when their * children are shown. When path-limiter is in effect, * rewrite_parents() drops some commits from getting shown, diff --combined sha1_name.c index 6ffee22081,5cf5578af1..6d7cd78381 --- a/sha1_name.c +++ b/sha1_name.c @@@ -157,7 -157,7 +157,7 @@@ static int get_short_sha1(const char *n char canonical[40]; unsigned char res[20]; - if (len < MINIMUM_ABBREV) + if (len < MINIMUM_ABBREV || len > 40) return -1; hashclr(res); memset(canonical, 'x', 40); @@@ -247,26 -247,25 +247,25 @@@ static int get_sha1_basic(const char *s NULL }; static const char *warning = "warning: refname '%.*s' is ambiguous.\n"; - const char **p, *pathname; - char *real_path = NULL; - int refs_found = 0, am; - unsigned long at_time = (unsigned long)-1; + const char **p, *ref; + char *real_ref = NULL; + int refs_found = 0; + int at, reflog_len; unsigned char *this_result; unsigned char sha1_from_ref[20]; if (len == 40 && !get_sha1_hex(str, sha1)) return 0; - /* At a given period of time? "@{2 hours ago}" */ - for (am = 1; am < len - 1; am++) { - if (str[am] == '@' && str[am+1] == '{' && str[len-1] == '}') { - int date_len = len - am - 3; - char *date_spec = xmalloc(date_len + 1); - strlcpy(date_spec, str + am + 2, date_len + 1); - at_time = approxidate(date_spec); - free(date_spec); - len = am; - break; + /* basic@{time or number} format to query ref-log */ + reflog_len = at = 0; + if (str[len-1] == '}') { + for (at = 1; at < len - 1; at++) { + if (str[at] == '@' && str[at+1] == '{') { + reflog_len = (len-1) - (at+2); + len = at; + break; + } } } @@@ -276,10 -275,10 +275,10 @@@ for (p = fmt; *p; p++) { this_result = refs_found ? sha1_from_ref : sha1; - pathname = resolve_ref(git_path(*p, len, str), this_result, 1); - if (pathname) { + ref = resolve_ref(mkpath(*p, len, str), this_result, 1, NULL); + if (ref) { if (!refs_found++) - real_path = xstrdup(pathname); + real_ref = xstrdup(ref); if (!warn_ambiguous_refs) break; } @@@ -291,14 -290,25 +290,25 @@@ if (warn_ambiguous_refs && refs_found > 1) fprintf(stderr, warning, len, str); - if (at_time != (unsigned long)-1) { - read_ref_at( - real_path + strlen(git_path(".")) - 1, - at_time, - sha1); + if (reflog_len) { + /* Is it asking for N-th entry, or approxidate? */ + int nth, i; + unsigned long at_time; + for (i = nth = 0; 0 <= nth && i < reflog_len; i++) { + char ch = str[at+2+i]; + if ('0' <= ch && ch <= '9') + nth = nth * 10 + ch - '0'; + else + nth = -1; + } + if (0 <= nth) + at_time = 0; + else + at_time = approxidate(str + at + 2); + read_ref_at(real_ref, at_time, nth, sha1); } - free(real_path); + free(real_ref); return 0; } diff --combined upload-pack.c index 9ec3775049,9412a9b260..ddaa72f0a9 --- a/upload-pack.c +++ b/upload-pack.c @@@ -16,7 -16,7 +16,7 @@@ static const char upload_pack_usage[] #define OUR_REF (1U << 1) #define WANTED (1U << 2) static int multi_ack, nr_our_refs; -static int use_thin_pack; +static int use_thin_pack, use_ofs_delta; static struct object_array have_obj; static struct object_array want_obj; static unsigned int timeout; @@@ -137,9 -137,7 +137,9 @@@ static void create_pack_file(void close(pu_pipe[1]); close(pe_pipe[0]); close(pe_pipe[1]); - execl_git_cmd("pack-objects", "--stdout", "--progress", NULL); + execl_git_cmd("pack-objects", "--stdout", "--progress", + use_ofs_delta ? "--delta-base-offset" : NULL, + NULL); kill(pid_rev_list, SIGKILL); die("git-upload-pack: unable to exec git-pack-objects"); } @@@ -395,8 -393,6 +395,8 @@@ static void receive_needs(void multi_ack = 1; if (strstr(line+45, "thin-pack")) use_thin_pack = 1; + if (strstr(line+45, "ofs-delta")) + use_ofs_delta = 1; if (strstr(line+45, "side-band-64k")) use_sideband = LARGE_PACKET_MAX; else if (strstr(line+45, "side-band")) @@@ -420,9 -416,9 +420,9 @@@ } } - static int send_ref(const char *refname, const unsigned char *sha1) + static int send_ref(const char *refname, const unsigned char *sha1, int flag, void *cb_data) { - static const char *capabilities = "multi_ack thin-pack side-band side-band-64k"; + static const char *capabilities = "multi_ack thin-pack side-band side-band-64k ofs-delta"; struct object *o = parse_object(sha1); if (!o) @@@ -448,8 -444,8 +448,8 @@@ static void upload_pack(void) { reset_timeout(); - head_ref(send_ref); - for_each_ref(send_ref); + head_ref(send_ref, NULL); + for_each_ref(send_ref, NULL); packet_flush(1); receive_needs(); if (want_obj.nr) { diff --combined wt-status.c index 3952809c2a,d8e284c311..7dd68575d1 --- a/wt-status.c +++ b/wt-status.c @@@ -41,10 -41,8 +41,8 @@@ void wt_status_prepare(struct wt_statu s->is_initial = get_sha1("HEAD", sha1) ? 1 : 0; - head = resolve_ref(git_path("HEAD"), sha1, 0); - s->branch = head ? - strdup(head + strlen(get_git_dir()) + 1) : - NULL; + head = resolve_ref("HEAD", sha1, 0, NULL); + s->branch = head ? xstrdup(head) : NULL; s->reference = "HEAD"; s->amend = 0; @@@ -72,25 -70,25 +70,25 @@@ static void wt_status_print_filepair(in color_printf(color(WT_STATUS_HEADER), "#\t"); switch (p->status) { case DIFF_STATUS_ADDED: - color_printf(c, "new file: %s", p->one->path); break; + color_printf(c, "new file: %s", p->one->path); break; case DIFF_STATUS_COPIED: - color_printf(c, "copied: %s -> %s", + color_printf(c, "copied: %s -> %s", p->one->path, p->two->path); break; case DIFF_STATUS_DELETED: - color_printf(c, "deleted: %s", p->one->path); break; + color_printf(c, "deleted: %s", p->one->path); break; case DIFF_STATUS_MODIFIED: - color_printf(c, "modified: %s", p->one->path); break; + color_printf(c, "modified: %s", p->one->path); break; case DIFF_STATUS_RENAMED: - color_printf(c, "renamed: %s -> %s", + color_printf(c, "renamed: %s -> %s", p->one->path, p->two->path); break; case DIFF_STATUS_TYPE_CHANGED: color_printf(c, "typechange: %s", p->one->path); break; case DIFF_STATUS_UNKNOWN: - color_printf(c, "unknown: %s", p->one->path); break; + color_printf(c, "unknown: %s", p->one->path); break; case DIFF_STATUS_UNMERGED: - color_printf(c, "unmerged: %s", p->one->path); break; + color_printf(c, "unmerged: %s", p->one->path); break; default: die("bug: unhandled diff status %c", p->status); }