diff options
46 files changed, 895 insertions, 257 deletions
diff --git a/Documentation/diff-format.txt b/Documentation/diff-format.txt index b426a14f5e..97756ec030 100644 --- a/Documentation/diff-format.txt +++ b/Documentation/diff-format.txt @@ -81,7 +81,7 @@ The "diff" formatting options can be customized via the environment variable 'GIT_DIFF_OPTS'. For example, if you prefer context diff: - GIT_DIFF_OPTS=-c git-diff-index -p $(cat .git/HEAD) + GIT_DIFF_OPTS=-c git-diff-index -p HEAD 2. When the environment variable 'GIT_EXTERNAL_DIFF' is set, the diff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt index 8eef86e474..6b496ede25 100644 --- a/Documentation/diff-options.txt +++ b/Documentation/diff-options.txt @@ -13,6 +13,11 @@ --name-status:: Show only names and status of changed files. +--full-index:: + Instead of the first handful characters, show full + object name of pre- and post-image blob on the "index" + line when generating a patch format output. + -B:: Break complete rewrite changes into pairs of delete and create. diff --git a/Documentation/git-apply.txt b/Documentation/git-apply.txt index 6702a18c7e..626e281596 100644 --- a/Documentation/git-apply.txt +++ b/Documentation/git-apply.txt @@ -8,7 +8,7 @@ git-apply - Apply patch on a git index file and a work tree SYNOPSIS -------- -'git-apply' [--stat] [--numstat] [--summary] [--check] [--index] [--apply] [--no-add] [--index-info] [-z] [<patch>...] +'git-apply' [--stat] [--numstat] [--summary] [--check] [--index] [--apply] [--no-add] [--index-info] [--allow-binary-replacement] [-z] [<patch>...] DESCRIPTION ----------- @@ -79,6 +79,17 @@ OPTIONS the result with this option, which would apply the deletion part but not addition part. +--allow-binary-replacement:: + When applying a patch, which is a git-enhanced patch + that was prepared to record the pre- and post-image object + name in full, and the path being patched exactly matches + the object the patch applies to (i.e. "index" line's + pre-image object name is what is in the working tree), + and the post-image object is available in the object + database, use the post-image object as the patch + result. This allows binary files to be patched in a + very limited way. + Author ------ Written by Linus Torvalds <torvalds@osdl.org> diff --git a/Documentation/git-commit-tree.txt b/Documentation/git-commit-tree.txt index 5cf6bd3e21..a794192d7b 100644 --- a/Documentation/git-commit-tree.txt +++ b/Documentation/git-commit-tree.txt @@ -26,8 +26,9 @@ to get there. Normally a commit would identify a new "HEAD" state, and while git doesn't care where you 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. +tend to just write the result to the file that is pointed at by +`.git/HEAD`, so that we can always see what the last committed +state was. OPTIONS ------- diff --git a/Documentation/git-daemon.txt b/Documentation/git-daemon.txt index 67c5f22a7d..3783858302 100644 --- a/Documentation/git-daemon.txt +++ b/Documentation/git-daemon.txt @@ -35,7 +35,7 @@ OPTIONS do not have the 'git-daemon-export-ok' file. --inetd:: - Have the server run as an inetd service. + Have the server run as an inetd service. Implies --syslog. --port:: Listen on an alternative port. diff --git a/Documentation/git-diff-index.txt b/Documentation/git-diff-index.txt index d8fc78fab9..dba6d30fcf 100644 --- a/Documentation/git-diff-index.txt +++ b/Documentation/git-diff-index.txt @@ -57,14 +57,14 @@ some files in the index and are ready to commit. You want to see eactly *what* you are going to commit is without having to write a new tree object and compare it that way, and to do that, you just do - git-diff-index --cached $(cat .git/HEAD) + git-diff-index --cached HEAD Example: let's say I had renamed `commit.c` to `git-commit.c`, and I had done an "git-update-index" to make that effective in the index file. "git-diff-files" wouldn't show anything at all, since the index file matches my working directory. But doing a "git-diff-index" does: - torvalds@ppc970:~/git> git-diff-index --cached $(cat .git/HEAD) + torvalds@ppc970:~/git> git-diff-index --cached HEAD -100644 blob 4161aecc6700a2eb579e842af0b7f22b98443f74 commit.c +100644 blob 4161aecc6700a2eb579e842af0b7f22b98443f74 git-commit.c @@ -98,7 +98,7 @@ show that. So let's say that you have edited `kernel/sched.c`, but have not actually done a "git-update-index" on it yet - there is no "object" associated with the new state, and you get: - torvalds@ppc970:~/v2.6/linux> git-diff-index $(cat .git/HEAD ) + torvalds@ppc970:~/v2.6/linux> git-diff-index HEAD *100644->100664 blob 7476bb......->000000...... kernel/sched.c ie it shows that the tree has changed, and that `kernel/sched.c` has is diff --git a/Documentation/git-fsck-objects.txt b/Documentation/git-fsck-objects.txt index 37e8055d21..bab1f6080c 100644 --- a/Documentation/git-fsck-objects.txt +++ b/Documentation/git-fsck-objects.txt @@ -68,7 +68,7 @@ that aren't readable from any of the specified head nodes. So for example - git-fsck-objects --unreachable $(cat .git/HEAD .git/refs/heads/*) + git-fsck-objects --unreachable HEAD $(cat .git/refs/heads/*) will do quite a _lot_ of verification on the tree. There are a few extra validity tests to be added (make sure that tree objects are diff --git a/Documentation/git-log.txt b/Documentation/git-log.txt index 9cac0886cf..e995d1b74b 100644 --- a/Documentation/git-log.txt +++ b/Documentation/git-log.txt @@ -20,7 +20,7 @@ This manual page describes only the most frequently used options. OPTIONS ------- ---pretty=<format>: +--pretty=<format>:: Controls the way the commit log is formatted. --max-count=<n>:: diff --git a/Documentation/git-read-tree.txt b/Documentation/git-read-tree.txt index 7be0cbd620..8b91847856 100644 --- a/Documentation/git-read-tree.txt +++ b/Documentation/git-read-tree.txt @@ -237,7 +237,7 @@ This is done to prevent you from losing your work-in-progress changes. To illustrate, suppose you start from what has been commited last to your repository: - $ JC=`cat .git/HEAD` + $ JC=`git-rev-parse --verify "HEAD^0"` $ git-checkout-index -f -u -a $JC You do random edits, without running git-update-index. And then diff --git a/Documentation/git-symbolic-ref.txt b/Documentation/git-symbolic-ref.txt index a851ae24c4..68ac6a65df 100644 --- a/Documentation/git-symbolic-ref.txt +++ b/Documentation/git-symbolic-ref.txt @@ -24,8 +24,8 @@ Traditionally, `.git/HEAD` is a symlink pointing at we did `ln -sf refs/heads/newbranch .git/HEAD`, and when we want to find out which branch we are on, we did `readlink .git/HEAD`. This was fine, and internally that is what still happens by -default, but on platforms that does not have working symlinks, -or that does not have the `readlink(1)` command, this was a bit +default, but on platforms that do not have working symlinks, +or that do not have the `readlink(1)` command, this was a bit cumbersome. On some platforms, `ln -sf` does not even work as advertised (horrors). diff --git a/Documentation/git.txt b/Documentation/git.txt index 7045f3f97e..338e5acb8b 100644 --- a/Documentation/git.txt +++ b/Documentation/git.txt @@ -8,13 +8,33 @@ git - the stupid content tracker SYNOPSIS -------- -'git-<command>' <args> +'git' [--version] [--exec-path[=GIT_EXEC_PATH]] [--help] COMMAND [ARGS] DESCRIPTION ----------- - -This is reference information for the core git commands. - +'git' is both a program and a directory content tracker system. +The program 'git' is just a wrapper to reach the core git programs +(or a potty if you like, as it's not exactly porcelain but still +brings your stuff to the plumbing). + +OPTIONS +------- +--version:: + prints the git suite version that the 'git' program came from. + +--help:: + prints the synopsis and a list of available commands. + If a git command is named this option will bring up the + man-page for that command. + +--exec-path:: + path to wherever your core git programs are installed. + This can also be controlled by setting the GIT_EXEC_PATH + environment variable. If no path is given 'git' will print + the current setting and then exit. + +CORE GIT COMMANDS +----------------- Before reading this cover to cover, you may want to take a look at the link:tutorial.html[tutorial] document. @@ -67,7 +87,7 @@ gitlink:git-commit-tree[1]:: gitlink:git-hash-object[1]:: Computes the object ID from a file. -gitlink:git-index-pack.html[1]:: +gitlink:git-index-pack[1]:: Build pack index file for an existing packed archive. gitlink:git-init-db[1]:: @@ -533,9 +553,12 @@ Discussion[[Discussion]] ------------------------ include::../README[] -Author ------- -Written by Linus Torvalds <torvalds@osdl.org> and the git-list <git@vger.kernel.org>. +Authors +------- + git's founding father is Linus Torvalds <torvalds@osdl.org>. + The current git nurse is Junio C. Hamano <junkio@cox.net>. + The git potty was written by Andres Ericsson <ae@op5.se>. + General upbringing is handled by the git-list <git@vger.kernel.org>. Documentation -------------- @@ -50,7 +50,7 @@ # Define USE_STDEV below if you want git to care about the underlying device # change being considered an inode change from the update-cache perspective. -GIT_VERSION = 0.99.9i +GIT_VERSION = 0.99.9j # CFLAGS and LDFLAGS are for the users to override from the command line. @@ -88,7 +88,7 @@ SCRIPT_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-tag.sh git-verify-tag.sh git-whatchanged.sh git.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 \ git-merge-resolve.sh git-merge-ours.sh git-grep.sh \ @@ -105,7 +105,7 @@ SCRIPT_PYTHON = \ # The ones that do not have to link with lcrypto nor lz. SIMPLE_PROGRAMS = \ git-get-tar-commit-id$X git-mailinfo$X git-mailsplit$X \ - git-stripspace$X git-var$X git-daemon$X + git-stripspace$X git-daemon$X # ... and all the rest PROGRAMS = \ @@ -125,7 +125,7 @@ PROGRAMS = \ git-unpack-objects$X git-update-index$X git-update-server-info$X \ git-upload-pack$X git-verify-pack$X git-write-tree$X \ git-update-ref$X git-symbolic-ref$X git-check-ref-format$X \ - git-name-rev$X git-pack-redundant$X $(SIMPLE_PROGRAMS) + git-name-rev$X git-pack-redundant$X git-var$X $(SIMPLE_PROGRAMS) # Backward compatibility -- to be removed after 1.0 PROGRAMS += git-ssh-pull$X git-ssh-push$X @@ -334,19 +334,15 @@ SCRIPTS = $(patsubst %.sh,%,$(SCRIPT_SH)) \ export prefix TAR INSTALL DESTDIR SHELL_PATH template_dir ### Build rules -all: $(PROGRAMS) $(SCRIPTS) +all: $(PROGRAMS) $(SCRIPTS) git all: $(MAKE) -C templates -git: git.sh Makefile - rm -f $@+ $@ - sed -e '1s|#!.*/sh|#!$(call shq,$(SHELL_PATH))|' \ - -e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \ - -e 's/@@X@@/$(X)/g' \ - $(GIT_LIST_TWEAK) <$@.sh >$@+ - chmod +x $@+ - mv $@+ $@ +# Only use $(CFLAGS). We don't need anything else. +git: git.c Makefile + $(CC) -DGIT_EXEC_PATH='"$(bindir)"' -DGIT_VERSION='"$(GIT_VERSION)"' \ + $(CFLAGS) $@.c -o $@ $(filter-out git,$(patsubst %.sh,%,$(SCRIPT_SH))) : % : %.sh rm -f $@ @@ -431,9 +427,9 @@ check: ### Installation rules -install: $(PROGRAMS) $(SCRIPTS) +install: $(PROGRAMS) $(SCRIPTS) git $(INSTALL) -d -m755 $(call shellquote,$(DESTDIR)$(bindir)) - $(INSTALL) $(PROGRAMS) $(SCRIPTS) $(call shellquote,$(DESTDIR)$(bindir)) + $(INSTALL) git $(PROGRAMS) $(SCRIPTS) $(call shellquote,$(DESTDIR)$(bindir)) $(MAKE) -C templates install $(INSTALL) -d -m755 $(call shellquote,$(DESTDIR)$(GIT_PYTHON_DIR)) $(INSTALL) $(PYMODULES) $(call shellquote,$(DESTDIR)$(GIT_PYTHON_DIR)) @@ -446,20 +442,20 @@ install-doc: ### Maintainer's dist rules -git-core.spec: git-core.spec.in Makefile +git.spec: git.spec.in Makefile sed -e 's/@@VERSION@@/$(GIT_VERSION)/g' < $< > $@ -GIT_TARNAME=git-core-$(GIT_VERSION) -dist: git-core.spec git-tar-tree +GIT_TARNAME=git-$(GIT_VERSION) +dist: git.spec git-tar-tree ./git-tar-tree HEAD $(GIT_TARNAME) > $(GIT_TARNAME).tar @mkdir -p $(GIT_TARNAME) - @cp git-core.spec $(GIT_TARNAME) - $(TAR) rf $(GIT_TARNAME).tar $(GIT_TARNAME)/git-core.spec + @cp git.spec $(GIT_TARNAME) + $(TAR) rf $(GIT_TARNAME).tar $(GIT_TARNAME)/git.spec @rm -rf $(GIT_TARNAME) gzip -f -9 $(GIT_TARNAME).tar rpm: dist - $(RPMBUILD) -ta git-core-$(GIT_VERSION).tar.gz + $(RPMBUILD) -ta $(GIT_TARNAME).tar.gz deb: dist rm -rf $(GIT_TARNAME) @@ -472,7 +468,7 @@ deb: dist clean: rm -f *.o mozilla-sha1/*.o ppc/*.o compat/*.o $(PROGRAMS) $(LIB_FILE) rm -f $(filter-out gitk,$(SCRIPTS)) - rm -f git-core.spec *.pyc *.pyo + rm -f *.spec *.pyc *.pyo rm -rf $(GIT_TARNAME) rm -f $(GIT_TARNAME).tar.gz git-core_$(GIT_VERSION)-*.tar.gz rm -f git-core_$(GIT_VERSION)-*.dsc @@ -396,8 +396,8 @@ git-commit-tree will return the name of the object that represents that commit, and you should save it away for later use. Normally, you'd commit a new `HEAD` state, and while git doesn't care where you 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. +result to the file pointed at by `.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. @@ -464,7 +464,7 @@ tend to be small and fairly self-explanatory. In particular, if you follow the convention of having the top commit name in `.git/HEAD`, you can do - git-cat-file commit $(cat .git/HEAD) + git-cat-file commit HEAD to see what the top commit was. @@ -16,6 +16,7 @@ // --numstat does numeric diffstat, and doesn't actually apply // --index-info shows the old and new index info for paths if available. // +static int allow_binary_replacement = 0; static int check_index = 0; static int write_index = 0; static int diffstat = 0; @@ -27,7 +28,7 @@ static int no_add = 0; static int show_index_info = 0; static int line_termination = '\n'; static const char apply_usage[] = -"git-apply [--stat] [--numstat] [--summary] [--check] [--index] [--apply] [--no-add] [--index-info] [-z] <patch>..."; +"git-apply [--stat] [--numstat] [--summary] [--check] [--index] [--apply] [--no-add] [--index-info] [--allow-binary-replacement] [-z] <patch>..."; /* * For "diff-stat" like behaviour, we keep track of the biggest change @@ -891,7 +892,7 @@ static int parse_chunk(char *buffer, unsigned long size, struct patch *patch) patchsize = parse_single_patch(buffer + offset + hdrsize, size - offset - hdrsize, patch); - if (!patchsize && !metadata_changes(patch)) { + if (!patchsize) { static const char binhdr[] = "Binary files "; if (sizeof(binhdr) - 1 < size - offset - hdrsize && @@ -899,9 +900,14 @@ static int parse_chunk(char *buffer, unsigned long size, struct patch *patch) sizeof(binhdr)-1)) patch->is_binary = 1; - if (patch->is_binary && !apply && !check) - ; - else + /* Empty patch cannot be applied if: + * - it is a binary patch and we do not do binary_replace, or + * - text patch without metadata change + */ + if ((apply || check) && + (patch->is_binary + ? !allow_binary_replacement + : !metadata_changes(patch))) die("patch with only garbage at line %d", linenr); } @@ -1155,10 +1161,77 @@ static int apply_one_fragment(struct buffer_desc *desc, struct fragment *frag) static int apply_fragments(struct buffer_desc *desc, struct patch *patch) { struct fragment *frag = patch->fragments; + const char *name = patch->old_name ? patch->old_name : patch->new_name; + + if (patch->is_binary) { + unsigned char sha1[20]; + + if (!allow_binary_replacement) + return error("cannot apply binary patch to '%s' " + "without --allow-binary-replacement", + name); + + /* For safety, we require patch index line to contain + * full 40-byte textual SHA1 for old and new, at least for now. + */ + if (strlen(patch->old_sha1_prefix) != 40 || + strlen(patch->new_sha1_prefix) != 40 || + get_sha1_hex(patch->old_sha1_prefix, sha1) || + get_sha1_hex(patch->new_sha1_prefix, sha1)) + return error("cannot apply binary patch to '%s' " + "without full index line", name); + + if (patch->old_name) { + unsigned char hdr[50]; + int hdrlen; + + /* See if the old one matches what the patch + * applies to. + */ + write_sha1_file_prepare(desc->buffer, desc->size, + "blob", sha1, hdr, &hdrlen); + if (strcmp(sha1_to_hex(sha1), patch->old_sha1_prefix)) + return error("the patch applies to '%s' (%s), " + "which does not match the " + "current contents.", + name, sha1_to_hex(sha1)); + } + else { + /* Otherwise, the old one must be empty. */ + if (desc->size) + return error("the patch applies to an empty " + "'%s' but it is not empty", name); + } + + /* For now, we do not record post-image data in the patch, + * and require the object already present in the recipient's + * object database. + */ + if (desc->buffer) { + free(desc->buffer); + desc->alloc = desc->size = 0; + } + get_sha1_hex(patch->new_sha1_prefix, sha1); + + if (memcmp(sha1, null_sha1, 20)) { + char type[10]; + unsigned long size; + + desc->buffer = read_sha1_file(sha1, type, &size); + if (!desc->buffer) + return error("the necessary postimage %s for " + "'%s' does not exist", + patch->new_sha1_prefix, name); + desc->alloc = desc->size = size; + } + + return 0; + } while (frag) { if (apply_one_fragment(desc, frag) < 0) - return error("patch failed: %s:%ld", patch->old_name, frag->oldpos); + return error("patch failed: %s:%ld", + name, frag->oldpos); frag = frag->next; } return 0; @@ -1200,6 +1273,7 @@ static int check_patch(struct patch *patch) struct stat st; const char *old_name = patch->old_name; const char *new_name = patch->new_name; + const char *name = old_name ? old_name : new_name; if (old_name) { int changed; @@ -1274,7 +1348,7 @@ static int check_patch(struct patch *patch) } if (apply_data(patch, &st) < 0) - return error("%s: patch does not apply", old_name); + return error("%s: patch does not apply", name); return 0; } @@ -1723,6 +1797,10 @@ int main(int argc, char **argv) diffstat = 1; continue; } + if (!strcmp(arg, "--allow-binary-replacement")) { + allow_binary_replacement = 1; + continue; + } if (!strcmp(arg, "--numstat")) { apply = 0; numstat = 1; @@ -179,6 +179,8 @@ extern int commit_index_file(struct cache_file *); extern void rollback_index_file(struct cache_file *); extern int trust_executable_bit; +extern int only_use_symrefs; +extern int diff_rename_limit_default; #define MTIME_CHANGED 0x0001 #define CTIME_CHANGED 0x0002 @@ -204,6 +204,7 @@ int parse_commit_buffer(struct commit *item, void *buffer, unsigned long size) unsigned char parent[20]; struct commit_list **pptr; struct commit_graft *graft; + unsigned n_refs = 0; if (item->object.parsed) return 0; @@ -214,7 +215,7 @@ int parse_commit_buffer(struct commit *item, void *buffer, unsigned long size) return error("bad tree pointer in commit %s\n", sha1_to_hex(item->object.sha1)); item->tree = lookup_tree(parent); if (item->tree) - add_ref(&item->object, &item->tree->object); + n_refs++; bufptr += 46; /* "tree " + "hex sha1" + "\n" */ pptr = &item->parents; @@ -230,7 +231,7 @@ int parse_commit_buffer(struct commit *item, void *buffer, unsigned long size) new_parent = lookup_commit(parent); if (new_parent) { pptr = &commit_list_insert(new_parent, pptr)->next; - add_ref(&item->object, &new_parent->object); + n_refs++; } } if (graft) { @@ -241,10 +242,22 @@ int parse_commit_buffer(struct commit *item, void *buffer, unsigned long size) if (!new_parent) continue; pptr = &commit_list_insert(new_parent, pptr)->next; - add_ref(&item->object, &new_parent->object); + n_refs++; } } item->date = parse_commit_date(bufptr); + + if (track_object_refs) { + unsigned i = 0; + struct commit_list *p; + struct object_refs *refs = alloc_object_refs(n_refs); + if (item->tree) + refs->ref[i++] = &item->tree->object; + for (p = item->parents; p; p = p->next) + refs->ref[i++] = &p->item->object; + set_object_refs(&item->object, refs); + } + return 0; } @@ -214,6 +214,11 @@ int git_default_config(const char *var, const char *value) return 0; } + if (!strcmp(var, "core.symrefsonly")) { + only_use_symrefs = git_config_bool(var, value); + return 0; + } + if (!strcmp(var, "user.name")) { strncpy(git_default_name, value, sizeof(git_default_name)); return 0; @@ -224,6 +229,11 @@ int git_default_config(const char *var, const char *value) return 0; } + if (!strcmp(var, "diff.renamelimit")) { + diff_rename_limit_default = git_config_int(var, value); + return 0; + } + /* Add other config variables here.. */ return 0; } @@ -594,6 +594,7 @@ int main(int argc, char **argv) } if (!strcmp(arg, "--inetd")) { inetd_mode = 1; + log_syslog = 1; continue; } if (!strcmp(arg, "--verbose")) { @@ -602,7 +603,6 @@ int main(int argc, char **argv) } if (!strcmp(arg, "--syslog")) { log_syslog = 1; - openlog("git-daemon", 0, LOG_DAEMON); continue; } if (!strcmp(arg, "--export-all")) { @@ -611,9 +611,11 @@ int main(int argc, char **argv) } if (!strncmp(arg, "--timeout=", 10)) { timeout = atoi(arg+10); + continue; } if (!strncmp(arg, "--init-timeout=", 15)) { init_timeout = atoi(arg+15); + continue; } if (!strcmp(arg, "--")) { ok_paths = &argv[i+1]; @@ -626,10 +628,13 @@ int main(int argc, char **argv) usage(daemon_usage); } + if (log_syslog) + openlog("git-daemon", 0, LOG_DAEMON); + if (inetd_mode) { fclose(stderr); //FIXME: workaround return execute(); - } else { - return serve(port); } + + return serve(port); } diff --git a/debian/changelog b/debian/changelog index 3d90d93f01..1eda61fe57 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +git-core (0.99.9j-0) unstable; urgency=low + + * GIT 0.99.9j aka 1.0rc3 + + -- Junio C Hamano <junkio@cox.net> Wed, 16 Nov 2005 20:39:55 -0800 + git-core (0.99.9i-0) unstable; urgency=low * GIT 0.99.9i aka 1.0rc2 @@ -13,6 +13,8 @@ static const char *diff_opts = "-pu"; static int use_size_cache; +int diff_rename_limit_default = -1; + static char *quote_one(const char *str) { int needlen; |