parent
							
								
									60d64db461
								
							
						
					
					
						commit
						27dedf0c3b
					
				|  | @ -81,7 +81,7 @@ The "diff" formatting options can be customized via the | ||||||
| environment variable 'GIT_DIFF_OPTS'.  For example, if you | environment variable 'GIT_DIFF_OPTS'.  For example, if you | ||||||
| prefer context diff: | 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 | 2. When the environment variable 'GIT_EXTERNAL_DIFF' is set, the | ||||||
|  |  | ||||||
|  | @ -13,6 +13,11 @@ | ||||||
| --name-status:: | --name-status:: | ||||||
| 	Show only names and status of changed files. | 	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:: | -B:: | ||||||
| 	Break complete rewrite changes into pairs of delete and create. | 	Break complete rewrite changes into pairs of delete and create. | ||||||
|  |  | ||||||
|  |  | ||||||
|  | @ -8,7 +8,7 @@ git-apply - Apply patch on a git index file and a work tree | ||||||
|  |  | ||||||
| SYNOPSIS | 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 | DESCRIPTION | ||||||
| ----------- | ----------- | ||||||
|  | @ -79,6 +79,17 @@ OPTIONS | ||||||
| 	the result with this option, which would apply the | 	the result with this option, which would apply the | ||||||
| 	deletion part but not addition part. | 	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 | Author | ||||||
| ------ | ------ | ||||||
| Written by Linus Torvalds <torvalds@osdl.org> | Written by Linus Torvalds <torvalds@osdl.org> | ||||||
|  |  | ||||||
|  | @ -26,8 +26,9 @@ to get there. | ||||||
|  |  | ||||||
| Normally a commit would identify a new "HEAD" state, and while git | 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 | 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 | tend to just write the result to the file that is pointed at by | ||||||
| always see what the last committed state was. | `.git/HEAD`, so that we can always see what the last committed | ||||||
|  | state was. | ||||||
|  |  | ||||||
| OPTIONS | OPTIONS | ||||||
| ------- | ------- | ||||||
|  |  | ||||||
|  | @ -35,7 +35,7 @@ OPTIONS | ||||||
| 	do not have the 'git-daemon-export-ok' file. | 	do not have the 'git-daemon-export-ok' file. | ||||||
|  |  | ||||||
| --inetd:: | --inetd:: | ||||||
| 	Have the server run as an inetd service. | 	Have the server run as an inetd service. Implies --syslog. | ||||||
|  |  | ||||||
| --port:: | --port:: | ||||||
| 	Listen on an alternative port. | 	Listen on an alternative port. | ||||||
|  |  | ||||||
|  | @ -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 | *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 | 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 | 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. | 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 | "git-diff-files" wouldn't show anything at all, since the index file | ||||||
| matches my working directory. But doing a "git-diff-index" does: | 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        commit.c | ||||||
|   +100644 blob    4161aecc6700a2eb579e842af0b7f22b98443f74        git-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 | have not actually done a "git-update-index" on it yet - there is no | ||||||
| "object" associated with the new state, and you get: | "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 |   *100644->100664 blob    7476bb......->000000......      kernel/sched.c | ||||||
|  |  | ||||||
| ie it shows that the tree has changed, and that `kernel/sched.c` has is | ie it shows that the tree has changed, and that `kernel/sched.c` has is | ||||||
|  |  | ||||||
|  | @ -68,7 +68,7 @@ that aren't readable from any of the specified head nodes. | ||||||
|  |  | ||||||
| So for example | 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 | 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 | extra validity tests to be added (make sure that tree objects are | ||||||
|  |  | ||||||
|  | @ -20,7 +20,7 @@ This manual page describes only the most frequently used options. | ||||||
|  |  | ||||||
| OPTIONS | OPTIONS | ||||||
| ------- | ------- | ||||||
| --pretty=<format>: | --pretty=<format>:: | ||||||
| 	Controls the way the commit log is formatted. | 	Controls the way the commit log is formatted. | ||||||
|  |  | ||||||
| --max-count=<n>:: | --max-count=<n>:: | ||||||
|  |  | ||||||
|  | @ -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 | changes.  To illustrate, suppose you start from what has been | ||||||
| commited last to your repository: | commited last to your repository: | ||||||
|  |  | ||||||
|     $ JC=`cat .git/HEAD` |     $ JC=`git-rev-parse --verify "HEAD^0"` | ||||||
|     $ git-checkout-index -f -u -a $JC |     $ git-checkout-index -f -u -a $JC | ||||||
|  |  | ||||||
| You do random edits, without running git-update-index.  And then | You do random edits, without running git-update-index.  And then | ||||||
|  |  | ||||||
|  | @ -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 | 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`. | to find out which branch we are on, we did `readlink .git/HEAD`. | ||||||
| This was fine, and internally that is what still happens by | This was fine, and internally that is what still happens by | ||||||
| default, but on platforms that does not have working symlinks, | default, but on platforms that do not have working symlinks, | ||||||
| or that does not have the `readlink(1)` command, this was a bit | or that do not have the `readlink(1)` command, this was a bit | ||||||
| cumbersome.  On some platforms, `ln -sf` does not even work as | cumbersome.  On some platforms, `ln -sf` does not even work as | ||||||
| advertised (horrors). | advertised (horrors). | ||||||
|  |  | ||||||
|  |  | ||||||
|  | @ -8,13 +8,33 @@ git - the stupid content tracker | ||||||
|  |  | ||||||
| SYNOPSIS | SYNOPSIS | ||||||
| -------- | -------- | ||||||
| 'git-<command>' <args> | 'git' [--version] [--exec-path[=GIT_EXEC_PATH]] [--help] COMMAND [ARGS] | ||||||
|  |  | ||||||
| DESCRIPTION | DESCRIPTION | ||||||
| ----------- | ----------- | ||||||
|  | '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). | ||||||
|  |  | ||||||
| This is reference information for the core git commands. | 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 | Before reading this cover to cover, you may want to take a look | ||||||
| at the link:tutorial.html[tutorial] document. | at the link:tutorial.html[tutorial] document. | ||||||
|  |  | ||||||
|  | @ -67,7 +87,7 @@ gitlink:git-commit-tree[1]:: | ||||||
| gitlink:git-hash-object[1]:: | gitlink:git-hash-object[1]:: | ||||||
| 	Computes the object ID from a file. | 	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. | 	Build pack index file for an existing packed archive. | ||||||
|  |  | ||||||
| gitlink:git-init-db[1]:: | gitlink:git-init-db[1]:: | ||||||
|  | @ -533,9 +553,12 @@ Discussion[[Discussion]] | ||||||
| ------------------------ | ------------------------ | ||||||
| include::../README[] | include::../README[] | ||||||
|  |  | ||||||
| Author | Authors | ||||||
| ------ | ------- | ||||||
| Written by Linus Torvalds <torvalds@osdl.org> and the git-list <git@vger.kernel.org>. | 	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 | Documentation | ||||||
| -------------- | -------------- | ||||||
|  |  | ||||||
							
								
								
									
										40
									
								
								Makefile
								
								
								
								
							
							
						
						
									
										40
									
								
								Makefile
								
								
								
								
							|  | @ -50,7 +50,7 @@ | ||||||
| # Define USE_STDEV below if you want git to care about the underlying device | # 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. | # 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. | # 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-prune.sh git-pull.sh git-push.sh git-rebase.sh \ | ||||||
| 	git-repack.sh git-request-pull.sh git-reset.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-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-applymbox.sh git-applypatch.sh git-am.sh \ | ||||||
| 	git-merge.sh git-merge-stupid.sh git-merge-octopus.sh \ | 	git-merge.sh git-merge-stupid.sh git-merge-octopus.sh \ | ||||||
| 	git-merge-resolve.sh git-merge-ours.sh git-grep.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. | # The ones that do not have to link with lcrypto nor lz. | ||||||
| SIMPLE_PROGRAMS = \ | SIMPLE_PROGRAMS = \ | ||||||
| 	git-get-tar-commit-id$X git-mailinfo$X git-mailsplit$X \ | 	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 | # ... and all the rest | ||||||
| PROGRAMS = \ | PROGRAMS = \ | ||||||
|  | @ -125,7 +125,7 @@ PROGRAMS = \ | ||||||
| 	git-unpack-objects$X git-update-index$X git-update-server-info$X \ | 	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-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-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 | # Backward compatibility -- to be removed after 1.0 | ||||||
| PROGRAMS += git-ssh-pull$X git-ssh-push$X | 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 | export prefix TAR INSTALL DESTDIR SHELL_PATH template_dir | ||||||
| ### Build rules | ### Build rules | ||||||
|  |  | ||||||
| all: $(PROGRAMS) $(SCRIPTS) | all: $(PROGRAMS) $(SCRIPTS) git | ||||||
|  |  | ||||||
| all: | all: | ||||||
| 	$(MAKE) -C templates | 	$(MAKE) -C templates | ||||||
|  |  | ||||||
| git: git.sh Makefile | # Only use $(CFLAGS). We don't need anything else. | ||||||
| 	rm -f $@+ $@ | git: git.c Makefile | ||||||
| 	sed -e '1s|#!.*/sh|#!$(call shq,$(SHELL_PATH))|' \ | 	$(CC) -DGIT_EXEC_PATH='"$(bindir)"' -DGIT_VERSION='"$(GIT_VERSION)"' \ | ||||||
| 	    -e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \ | 		$(CFLAGS) $@.c -o $@ | ||||||
| 	    -e 's/@@X@@/$(X)/g' \ |  | ||||||
| 	    $(GIT_LIST_TWEAK) <$@.sh >$@+ |  | ||||||
| 	chmod +x $@+ |  | ||||||
| 	mv $@+ $@ |  | ||||||
|  |  | ||||||
| $(filter-out git,$(patsubst %.sh,%,$(SCRIPT_SH))) : % : %.sh | $(filter-out git,$(patsubst %.sh,%,$(SCRIPT_SH))) : % : %.sh | ||||||
| 	rm -f $@ | 	rm -f $@ | ||||||
|  | @ -431,9 +427,9 @@ check: | ||||||
|  |  | ||||||
| ### Installation rules | ### Installation rules | ||||||
|  |  | ||||||
| install: $(PROGRAMS) $(SCRIPTS) | install: $(PROGRAMS) $(SCRIPTS) git | ||||||
| 	$(INSTALL) -d -m755 $(call shellquote,$(DESTDIR)$(bindir)) | 	$(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 | 	$(MAKE) -C templates install | ||||||
| 	$(INSTALL) -d -m755 $(call shellquote,$(DESTDIR)$(GIT_PYTHON_DIR)) | 	$(INSTALL) -d -m755 $(call shellquote,$(DESTDIR)$(GIT_PYTHON_DIR)) | ||||||
| 	$(INSTALL) $(PYMODULES) $(call shellquote,$(DESTDIR)$(GIT_PYTHON_DIR)) | 	$(INSTALL) $(PYMODULES) $(call shellquote,$(DESTDIR)$(GIT_PYTHON_DIR)) | ||||||
|  | @ -446,20 +442,20 @@ install-doc: | ||||||
|  |  | ||||||
| ### Maintainer's dist rules | ### 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' < $< > $@ | 	sed -e 's/@@VERSION@@/$(GIT_VERSION)/g' < $< > $@ | ||||||
|  |  | ||||||
| GIT_TARNAME=git-core-$(GIT_VERSION) | GIT_TARNAME=git-$(GIT_VERSION) | ||||||
| dist: git-core.spec git-tar-tree | dist: git.spec git-tar-tree | ||||||
| 	./git-tar-tree HEAD $(GIT_TARNAME) > $(GIT_TARNAME).tar | 	./git-tar-tree HEAD $(GIT_TARNAME) > $(GIT_TARNAME).tar | ||||||
| 	@mkdir -p $(GIT_TARNAME) | 	@mkdir -p $(GIT_TARNAME) | ||||||
| 	@cp git-core.spec $(GIT_TARNAME) | 	@cp git.spec $(GIT_TARNAME) | ||||||
| 	$(TAR) rf $(GIT_TARNAME).tar $(GIT_TARNAME)/git-core.spec | 	$(TAR) rf $(GIT_TARNAME).tar $(GIT_TARNAME)/git.spec | ||||||
| 	@rm -rf $(GIT_TARNAME) | 	@rm -rf $(GIT_TARNAME) | ||||||
| 	gzip -f -9 $(GIT_TARNAME).tar | 	gzip -f -9 $(GIT_TARNAME).tar | ||||||
|  |  | ||||||
| rpm: dist | rpm: dist | ||||||
| 	$(RPMBUILD) -ta git-core-$(GIT_VERSION).tar.gz | 	$(RPMBUILD) -ta $(GIT_TARNAME).tar.gz | ||||||
|  |  | ||||||
| deb: dist | deb: dist | ||||||
| 	rm -rf $(GIT_TARNAME) | 	rm -rf $(GIT_TARNAME) | ||||||
|  | @ -472,7 +468,7 @@ deb: dist | ||||||
| clean: | clean: | ||||||
| 	rm -f *.o mozilla-sha1/*.o ppc/*.o compat/*.o $(PROGRAMS) $(LIB_FILE) | 	rm -f *.o mozilla-sha1/*.o ppc/*.o compat/*.o $(PROGRAMS) $(LIB_FILE) | ||||||
| 	rm -f $(filter-out gitk,$(SCRIPTS)) | 	rm -f $(filter-out gitk,$(SCRIPTS)) | ||||||
| 	rm -f git-core.spec *.pyc *.pyo | 	rm -f *.spec *.pyc *.pyo | ||||||
| 	rm -rf $(GIT_TARNAME) | 	rm -rf $(GIT_TARNAME) | ||||||
| 	rm -f $(GIT_TARNAME).tar.gz git-core_$(GIT_VERSION)-*.tar.gz | 	rm -f $(GIT_TARNAME).tar.gz git-core_$(GIT_VERSION)-*.tar.gz | ||||||
| 	rm -f git-core_$(GIT_VERSION)-*.dsc | 	rm -f git-core_$(GIT_VERSION)-*.dsc | ||||||
|  |  | ||||||
							
								
								
									
										6
									
								
								README
								
								
								
								
							
							
						
						
									
										6
									
								
								README
								
								
								
								
							|  | @ -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, | 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 | 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 | 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 | result to the file pointed at by `.git/HEAD`, so that we can always see | ||||||
| last committed state was. | what the last committed state was. | ||||||
|  |  | ||||||
| Here is an ASCII art by Jon Loeliger that illustrates how | Here is an ASCII art by Jon Loeliger that illustrates how | ||||||
| various pieces fit together. | 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`, | follow the convention of having the top commit name in `.git/HEAD`, | ||||||
| you can do | you can do | ||||||
|  |  | ||||||
| 		git-cat-file commit $(cat .git/HEAD) | 		git-cat-file commit HEAD | ||||||
|  |  | ||||||
| to see what the top commit was. | to see what the top commit was. | ||||||
|  |  | ||||||
|  |  | ||||||
							
								
								
									
										92
									
								
								apply.c
								
								
								
								
							
							
						
						
									
										92
									
								
								apply.c
								
								
								
								
							|  | @ -16,6 +16,7 @@ | ||||||
| //  --numstat does numeric diffstat, and doesn't actually apply | //  --numstat does numeric diffstat, and doesn't actually apply | ||||||
| //  --index-info shows the old and new index info for paths if available. | //  --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 check_index = 0; | ||||||
| static int write_index = 0; | static int write_index = 0; | ||||||
| static int diffstat = 0; | static int diffstat = 0; | ||||||
|  | @ -27,7 +28,7 @@ static int no_add = 0; | ||||||
| static int show_index_info = 0; | static int show_index_info = 0; | ||||||
| static int line_termination = '\n'; | static int line_termination = '\n'; | ||||||
| static const char apply_usage[] = | 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 |  * 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); | 	patchsize = parse_single_patch(buffer + offset + hdrsize, size - offset - hdrsize, patch); | ||||||
|  |  | ||||||
| 	if (!patchsize && !metadata_changes(patch)) { | 	if (!patchsize) { | ||||||
| 		static const char binhdr[] = "Binary files "; | 		static const char binhdr[] = "Binary files "; | ||||||
|  |  | ||||||
| 		if (sizeof(binhdr) - 1 < size - offset - hdrsize && | 		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)) | 			    sizeof(binhdr)-1)) | ||||||
| 			patch->is_binary = 1; | 			patch->is_binary = 1; | ||||||
|  |  | ||||||
| 		if (patch->is_binary && !apply && !check) | 		/* Empty patch cannot be applied if: | ||||||
| 			; | 		 * - it is a binary patch and we do not do binary_replace, or | ||||||
| 		else | 		 * - 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); | 			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) | static int apply_fragments(struct buffer_desc *desc, struct patch *patch) | ||||||
| { | { | ||||||
| 	struct fragment *frag = patch->fragments; | 	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) { | 	while (frag) { | ||||||
| 		if (apply_one_fragment(desc, frag) < 0) | 		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; | 		frag = frag->next; | ||||||
| 	} | 	} | ||||||
| 	return 0; | 	return 0; | ||||||
|  | @ -1200,6 +1273,7 @@ static int check_patch(struct patch *patch) | ||||||
| 	struct stat st; | 	struct stat st; | ||||||
| 	const char *old_name = patch->old_name; | 	const char *old_name = patch->old_name; | ||||||
| 	const char *new_name = patch->new_name; | 	const char *new_name = patch->new_name; | ||||||
|  | 	const char *name = old_name ? old_name : new_name; | ||||||
|  |  | ||||||
| 	if (old_name) { | 	if (old_name) { | ||||||
| 		int changed; | 		int changed; | ||||||
|  | @ -1274,7 +1348,7 @@ static int check_patch(struct patch *patch) | ||||||
| 	}	 | 	}	 | ||||||
|  |  | ||||||
| 	if (apply_data(patch, &st) < 0) | 	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; | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -1723,6 +1797,10 @@ int main(int argc, char **argv) | ||||||
| 			diffstat = 1; | 			diffstat = 1; | ||||||
| 			continue; | 			continue; | ||||||
| 		} | 		} | ||||||
|  | 		if (!strcmp(arg, "--allow-binary-replacement")) { | ||||||
|  | 			allow_binary_replacement = 1; | ||||||
|  | 			continue; | ||||||
|  | 		} | ||||||
| 		if (!strcmp(arg, "--numstat")) { | 		if (!strcmp(arg, "--numstat")) { | ||||||
| 			apply = 0; | 			apply = 0; | ||||||
| 			numstat = 1; | 			numstat = 1; | ||||||
|  |  | ||||||
							
								
								
									
										2
									
								
								cache.h
								
								
								
								
							
							
						
						
									
										2
									
								
								cache.h
								
								
								
								
							|  | @ -179,6 +179,8 @@ extern int commit_index_file(struct cache_file *); | ||||||
| extern void rollback_index_file(struct cache_file *); | extern void rollback_index_file(struct cache_file *); | ||||||
|  |  | ||||||
| extern int trust_executable_bit; | extern int trust_executable_bit; | ||||||
|  | extern int only_use_symrefs; | ||||||
|  | extern int diff_rename_limit_default; | ||||||
|  |  | ||||||
| #define MTIME_CHANGED	0x0001 | #define MTIME_CHANGED	0x0001 | ||||||
| #define CTIME_CHANGED	0x0002 | #define CTIME_CHANGED	0x0002 | ||||||
|  |  | ||||||
							
								
								
									
										19
									
								
								commit.c
								
								
								
								
							
							
						
						
									
										19
									
								
								commit.c
								
								
								
								
							|  | @ -204,6 +204,7 @@ int parse_commit_buffer(struct commit *item, void *buffer, unsigned long size) | ||||||
| 	unsigned char parent[20]; | 	unsigned char parent[20]; | ||||||
| 	struct commit_list **pptr; | 	struct commit_list **pptr; | ||||||
| 	struct commit_graft *graft; | 	struct commit_graft *graft; | ||||||
|  | 	unsigned n_refs = 0; | ||||||
|  |  | ||||||
| 	if (item->object.parsed) | 	if (item->object.parsed) | ||||||
| 		return 0; | 		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)); | 		return error("bad tree pointer in commit %s\n", sha1_to_hex(item->object.sha1)); | ||||||
| 	item->tree = lookup_tree(parent); | 	item->tree = lookup_tree(parent); | ||||||
| 	if (item->tree) | 	if (item->tree) | ||||||
| 		add_ref(&item->object, &item->tree->object); | 		n_refs++; | ||||||
| 	bufptr += 46; /* "tree " + "hex sha1" + "\n" */ | 	bufptr += 46; /* "tree " + "hex sha1" + "\n" */ | ||||||
| 	pptr = &item->parents; | 	pptr = &item->parents; | ||||||
|  |  | ||||||
|  | @ -230,7 +231,7 @@ int parse_commit_buffer(struct commit *item, void *buffer, unsigned long size) | ||||||
| 		new_parent = lookup_commit(parent); | 		new_parent = lookup_commit(parent); | ||||||
| 		if (new_parent) { | 		if (new_parent) { | ||||||
| 			pptr = &commit_list_insert(new_parent, pptr)->next; | 			pptr = &commit_list_insert(new_parent, pptr)->next; | ||||||
| 			add_ref(&item->object, &new_parent->object); | 			n_refs++; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	if (graft) { | 	if (graft) { | ||||||
|  | @ -241,10 +242,22 @@ int parse_commit_buffer(struct commit *item, void *buffer, unsigned long size) | ||||||
| 			if (!new_parent) | 			if (!new_parent) | ||||||
| 				continue; | 				continue; | ||||||
| 			pptr = &commit_list_insert(new_parent, pptr)->next; | 			pptr = &commit_list_insert(new_parent, pptr)->next; | ||||||
| 			add_ref(&item->object, &new_parent->object); | 			n_refs++; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	item->date = parse_commit_date(bufptr); | 	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; | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
							
								
								
									
										10
									
								
								config.c
								
								
								
								
							
							
						
						
									
										10
									
								
								config.c
								
								
								
								
							|  | @ -214,6 +214,11 @@ int git_default_config(const char *var, const char *value) | ||||||
| 		return 0; | 		return 0; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	if (!strcmp(var, "core.symrefsonly")) { | ||||||
|  | 		only_use_symrefs = git_config_bool(var, value); | ||||||
|  | 		return 0; | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	if (!strcmp(var, "user.name")) { | 	if (!strcmp(var, "user.name")) { | ||||||
| 		strncpy(git_default_name, value, sizeof(git_default_name)); | 		strncpy(git_default_name, value, sizeof(git_default_name)); | ||||||
| 		return 0; | 		return 0; | ||||||
|  | @ -224,6 +229,11 @@ int git_default_config(const char *var, const char *value) | ||||||
| 		return 0; | 		return 0; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	if (!strcmp(var, "diff.renamelimit")) { | ||||||
|  | 		diff_rename_limit_default = git_config_int(var, value); | ||||||
|  | 		return 0; | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	/* Add other config variables here.. */ | 	/* Add other config variables here.. */ | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
							
								
								
									
										11
									
								
								daemon.c
								
								
								
								
							
							
						
						
									
										11
									
								
								daemon.c
								
								
								
								
							|  | @ -594,6 +594,7 @@ int main(int argc, char **argv) | ||||||
| 		} | 		} | ||||||
| 		if (!strcmp(arg, "--inetd")) { | 		if (!strcmp(arg, "--inetd")) { | ||||||
| 			inetd_mode = 1; | 			inetd_mode = 1; | ||||||
|  | 			log_syslog = 1; | ||||||
| 			continue; | 			continue; | ||||||
| 		} | 		} | ||||||
| 		if (!strcmp(arg, "--verbose")) { | 		if (!strcmp(arg, "--verbose")) { | ||||||
|  | @ -602,7 +603,6 @@ int main(int argc, char **argv) | ||||||
| 		} | 		} | ||||||
| 		if (!strcmp(arg, "--syslog")) { | 		if (!strcmp(arg, "--syslog")) { | ||||||
| 			log_syslog = 1; | 			log_syslog = 1; | ||||||
| 			openlog("git-daemon", 0, LOG_DAEMON); |  | ||||||
| 			continue; | 			continue; | ||||||
| 		} | 		} | ||||||
| 		if (!strcmp(arg, "--export-all")) { | 		if (!strcmp(arg, "--export-all")) { | ||||||
|  | @ -611,9 +611,11 @@ int main(int argc, char **argv) | ||||||
| 		} | 		} | ||||||
| 		if (!strncmp(arg, "--timeout=", 10)) { | 		if (!strncmp(arg, "--timeout=", 10)) { | ||||||
| 			timeout = atoi(arg+10); | 			timeout = atoi(arg+10); | ||||||
|  | 			continue; | ||||||
| 		} | 		} | ||||||
| 		if (!strncmp(arg, "--init-timeout=", 15)) { | 		if (!strncmp(arg, "--init-timeout=", 15)) { | ||||||
| 			init_timeout = atoi(arg+15); | 			init_timeout = atoi(arg+15); | ||||||
|  | 			continue; | ||||||
| 		} | 		} | ||||||
| 		if (!strcmp(arg, "--")) { | 		if (!strcmp(arg, "--")) { | ||||||
| 			ok_paths = &argv[i+1]; | 			ok_paths = &argv[i+1]; | ||||||
|  | @ -626,10 +628,13 @@ int main(int argc, char **argv) | ||||||
| 		usage(daemon_usage); | 		usage(daemon_usage); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	if (log_syslog) | ||||||
|  | 		openlog("git-daemon", 0, LOG_DAEMON); | ||||||
|  |  | ||||||
| 	if (inetd_mode) { | 	if (inetd_mode) { | ||||||
| 		fclose(stderr); //FIXME: workaround | 		fclose(stderr); //FIXME: workaround | ||||||
| 		return execute(); | 		return execute(); | ||||||
| 	} else { |  | ||||||
| 		return serve(port); |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	return serve(port); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -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-core (0.99.9i-0) unstable; urgency=low | ||||||
|  |  | ||||||
|   * GIT 0.99.9i aka 1.0rc2 |   * GIT 0.99.9i aka 1.0rc2 | ||||||
|  |  | ||||||
							
								
								
									
										23
									
								
								diff.c
								
								
								
								
							
							
						
						
									
										23
									
								
								diff.c
								
								
								
								
							|  | @ -13,6 +13,8 @@ static const char *diff_opts = "-pu"; | ||||||
|  |  | ||||||
| static int use_size_cache; | static int use_size_cache; | ||||||
|  |  | ||||||
|  | int diff_rename_limit_default = -1; | ||||||
|  |  | ||||||
| static char *quote_one(const char *str) | static char *quote_one(const char *str) | ||||||
| { | { | ||||||
| 	int needlen; | 	int needlen; | ||||||
|  | @ -648,7 +650,7 @@ static void diff_fill_sha1_info(struct diff_filespec *one) | ||||||
| 		memset(one->sha1, 0, 20); | 		memset(one->sha1, 0, 20); | ||||||
| } | } | ||||||
|  |  | ||||||
| static void run_diff(struct diff_filepair *p) | static void run_diff(struct diff_filepair *p, struct diff_options *o) | ||||||
| { | { | ||||||
| 	const char *pgm = external_diff(); | 	const char *pgm = external_diff(); | ||||||
| 	char msg[PATH_MAX*2+300], *xfrm_msg; | 	char msg[PATH_MAX*2+300], *xfrm_msg; | ||||||
|  | @ -711,11 +713,11 @@ static void run_diff(struct diff_filepair *p) | ||||||
|  |  | ||||||
| 	if (memcmp(one->sha1, two->sha1, 20)) { | 	if (memcmp(one->sha1, two->sha1, 20)) { | ||||||
| 		char one_sha1[41]; | 		char one_sha1[41]; | ||||||
|  | 		const char *index_fmt = o->full_index ? "index %s..%s" : "index %.7s..%.7s"; | ||||||
| 		memcpy(one_sha1, sha1_to_hex(one->sha1), 41); | 		memcpy(one_sha1, sha1_to_hex(one->sha1), 41); | ||||||
|  |  | ||||||
| 		len += snprintf(msg + len, sizeof(msg) - len, | 		len += snprintf(msg + len, sizeof(msg) - len, | ||||||
| 				"index %.7s..%.7s", one_sha1, | 				index_fmt, one_sha1, sha1_to_hex(two->sha1)); | ||||||
| 				sha1_to_hex(two->sha1)); |  | ||||||
| 		if (one->mode == two->mode) | 		if (one->mode == two->mode) | ||||||
| 			len += snprintf(msg + len, sizeof(msg) - len, | 			len += snprintf(msg + len, sizeof(msg) - len, | ||||||
| 					" %06o", one->mode); | 					" %06o", one->mode); | ||||||
|  | @ -761,9 +763,12 @@ void diff_setup(struct diff_options *options) | ||||||
|  |  | ||||||
| int diff_setup_done(struct diff_options *options) | int diff_setup_done(struct diff_options *options) | ||||||
| { | { | ||||||
| 	if ((options->find_copies_harder || 0 <= options->rename_limit) && | 	if ((options->find_copies_harder && | ||||||
| 	    options->detect_rename != DIFF_DETECT_COPY) | 	     options->detect_rename != DIFF_DETECT_COPY) || | ||||||
|  | 	    (0 <= options->rename_limit && !options->detect_rename)) | ||||||
| 		return -1; | 		return -1; | ||||||
|  | 	if (options->detect_rename && options->rename_limit < 0) | ||||||
|  | 		options->rename_limit = diff_rename_limit_default; | ||||||
| 	if (options->setup & DIFF_SETUP_USE_CACHE) { | 	if (options->setup & DIFF_SETUP_USE_CACHE) { | ||||||
| 		if (!active_cache) | 		if (!active_cache) | ||||||
| 			/* read-cache does not die even when it fails | 			/* read-cache does not die even when it fails | ||||||
|  | @ -789,6 +794,8 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac) | ||||||
| 		options->line_termination = 0; | 		options->line_termination = 0; | ||||||
| 	else if (!strncmp(arg, "-l", 2)) | 	else if (!strncmp(arg, "-l", 2)) | ||||||
| 		options->rename_limit = strtoul(arg+2, NULL, 10); | 		options->rename_limit = strtoul(arg+2, NULL, 10); | ||||||
|  | 	else if (!strcmp(arg, "--full-index")) | ||||||
|  | 		options->full_index = 1; | ||||||
| 	else if (!strcmp(arg, "--name-only")) | 	else if (!strcmp(arg, "--name-only")) | ||||||
| 		options->output_format = DIFF_FORMAT_NAME; | 		options->output_format = DIFF_FORMAT_NAME; | ||||||
| 	else if (!strcmp(arg, "--name-status")) | 	else if (!strcmp(arg, "--name-status")) | ||||||
|  | @ -1017,7 +1024,7 @@ int diff_unmodified_pair(struct diff_filepair *p) | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| static void diff_flush_patch(struct diff_filepair *p) | static void diff_flush_patch(struct diff_filepair *p, struct diff_options *o) | ||||||
| { | { | ||||||
| 	if (diff_unmodified_pair(p)) | 	if (diff_unmodified_pair(p)) | ||||||
| 		return; | 		return; | ||||||
|  | @ -1026,7 +1033,7 @@ static void diff_flush_patch(struct diff_filepair *p) | ||||||
| 	    (DIFF_FILE_VALID(p->two) && S_ISDIR(p->two->mode))) | 	    (DIFF_FILE_VALID(p->two) && S_ISDIR(p->two->mode))) | ||||||
| 		return; /* no tree diffs in patch format */  | 		return; /* no tree diffs in patch format */  | ||||||
|  |  | ||||||
| 	run_diff(p); | 	run_diff(p, o); | ||||||
| } | } | ||||||
|  |  | ||||||
| int diff_queue_is_empty(void) | int diff_queue_is_empty(void) | ||||||
|  | @ -1158,7 +1165,7 @@ void diff_flush(struct diff_options *options) | ||||||
| 			die("internal error in diff-resolve-rename-copy"); | 			die("internal error in diff-resolve-rename-copy"); | ||||||
| 		switch (diff_output_format) { | 		switch (diff_output_format) { | ||||||
| 		case DIFF_FORMAT_PATCH: | 		case DIFF_FORMAT_PATCH: | ||||||
| 			diff_flush_patch(p); | 			diff_flush_patch(p, options); | ||||||
| 			break; | 			break; | ||||||
| 		case DIFF_FORMAT_RAW: | 		case DIFF_FORMAT_RAW: | ||||||
| 		case DIFF_FORMAT_NAME_STATUS: | 		case DIFF_FORMAT_NAME_STATUS: | ||||||
|  |  | ||||||
							
								
								
									
										4
									
								
								diff.h
								
								
								
								
							
							
						
						
									
										4
									
								
								diff.h
								
								
								
								
							|  | @ -32,7 +32,8 @@ struct diff_options { | ||||||
| 	const char *orderfile; | 	const char *orderfile; | ||||||
| 	const char *pickaxe; | 	const char *pickaxe; | ||||||
| 	unsigned recursive:1, | 	unsigned recursive:1, | ||||||
| 		 tree_in_recursive:1; | 		 tree_in_recursive:1, | ||||||
|  | 		 full_index:1; | ||||||
| 	int break_opt; | 	int break_opt; | ||||||
| 	int detect_rename; | 	int detect_rename; | ||||||
| 	int find_copies_harder; | 	int find_copies_harder; | ||||||
|  | @ -96,6 +97,7 @@ extern void diffcore_std_no_resolve(struct diff_options *); | ||||||
| "  -u            synonym for -p.\n" \ | "  -u            synonym for -p.\n" \ | ||||||
| "  --name-only   show only names of changed files.\n" \ | "  --name-only   show only names of changed files.\n" \ | ||||||
| "  --name-status show names and status of changed files.\n" \ | "  --name-status show names and status of changed files.\n" \ | ||||||
|  | "  --full-index  show full object name on index ines.\n" \ | ||||||
| "  -R            swap input file pairs.\n" \ | "  -R            swap input file pairs.\n" \ | ||||||
| "  -B            detect complete rewrites.\n" \ | "  -B            detect complete rewrites.\n" \ | ||||||
| "  -M            detect renames.\n" \ | "  -M            detect renames.\n" \ | ||||||
|  |  | ||||||
|  | @ -283,7 +283,7 @@ void diffcore_rename(struct diff_options *options) | ||||||
| 			register_rename_src(p->one, 1); | 			register_rename_src(p->one, 1); | ||||||
| 	} | 	} | ||||||
| 	if (rename_dst_nr == 0 || | 	if (rename_dst_nr == 0 || | ||||||
| 	    (0 <= rename_limit && rename_limit < rename_dst_nr)) | 	    (0 < rename_limit && rename_limit < rename_dst_nr)) | ||||||
| 		goto cleanup; /* nothing to do */ | 		goto cleanup; /* nothing to do */ | ||||||
|  |  | ||||||
| 	/* We really want to cull the candidates list early | 	/* We really want to cull the candidates list early | ||||||
|  |  | ||||||
|  | @ -12,6 +12,7 @@ | ||||||
| char git_default_email[MAX_GITNAME]; | char git_default_email[MAX_GITNAME]; | ||||||
| char git_default_name[MAX_GITNAME]; | char git_default_name[MAX_GITNAME]; | ||||||
| int trust_executable_bit = 1; | int trust_executable_bit = 1; | ||||||
|  | int only_use_symrefs = 0; | ||||||
|  |  | ||||||
| static char *git_dir, *git_object_dir, *git_index_file, *git_refs_dir, | static char *git_dir, *git_object_dir, *git_index_file, *git_refs_dir, | ||||||
| 	*git_graft_file; | 	*git_graft_file; | ||||||
|  |  | ||||||
|  | @ -56,7 +56,6 @@ static void check_connectivity(void) | ||||||
| 	/* Look up all the requirements, warn about missing objects.. */ | 	/* Look up all the requirements, warn about missing objects.. */ | ||||||
| 	for (i = 0; i < nr_objs; i++) { | 	for (i = 0; i < nr_objs; i++) { | ||||||
| 		struct object *obj = objs[i]; | 		struct object *obj = objs[i]; | ||||||
| 		struct object_list *refs; |  | ||||||
|  |  | ||||||
| 		if (!obj->parsed) { | 		if (!obj->parsed) { | ||||||
| 			if (!standalone && has_sha1_file(obj->sha1)) | 			if (!standalone && has_sha1_file(obj->sha1)) | ||||||
|  | @ -67,14 +66,19 @@ static void check_connectivity(void) | ||||||
| 			continue; | 			continue; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		for (refs = obj->refs; refs; refs = refs->next) { | 		if (obj->refs) { | ||||||
| 			if (refs->item->parsed || | 			const struct object_refs *refs = obj->refs; | ||||||
| 			    (!standalone && has_sha1_file(refs->item->sha1))) | 			unsigned j; | ||||||
| 				continue; | 			for (j = 0; j < refs->count; j++) { | ||||||
| 			printf("broken link from %7s %s\n", | 				struct object *ref = refs->ref[j]; | ||||||
| 			       obj->type, sha1_to_hex(obj->sha1)); | 				if (ref->parsed || | ||||||
| 			printf("              to %7s %s\n", | 				    (!standalone && has_sha1_file(ref->sha1))) | ||||||
| 			       refs->item->type, sha1_to_hex(refs->item->sha1)); | 					continue; | ||||||
|  | 				printf("broken link from %7s %s\n", | ||||||
|  | 				       obj->type, sha1_to_hex(obj->sha1)); | ||||||
|  | 				printf("              to %7s %s\n", | ||||||
|  | 				       ref->type, sha1_to_hex(ref->sha1)); | ||||||
|  | 			} | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if (show_unreachable && !(obj->flags & REACHABLE)) { | 		if (show_unreachable && !(obj->flags & REACHABLE)) { | ||||||
|  | @ -184,10 +188,17 @@ static int fsck_tree(struct tree *item) | ||||||
| 			default: | 			default: | ||||||
| 				break; | 				break; | ||||||
| 			} | 			} | ||||||
|  | 			free(last->name); | ||||||
|  | 			free(last); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		last = entry; | 		last = entry; | ||||||
| 	} | 	} | ||||||
|  | 	if (last) { | ||||||
|  | 		free(last->name); | ||||||
|  | 		free(last); | ||||||
|  | 	} | ||||||
|  | 	item->entries = NULL; | ||||||
|  |  | ||||||
| 	retval = 0; | 	retval = 0; | ||||||
| 	if (has_full_path) { | 	if (has_full_path) { | ||||||
|  |  | ||||||
							
								
								
									
										65
									
								
								git-am.sh
								
								
								
								
							
							
						
						
									
										65
									
								
								git-am.sh
								
								
								
								
							|  | @ -3,16 +3,10 @@ | ||||||
| # | # | ||||||
| . git-sh-setup || die "Not a git archive" | . git-sh-setup || die "Not a git archive" | ||||||
|  |  | ||||||
| files=$(git-diff-index --cached --name-only HEAD) || exit |  | ||||||
| if [ "$files" ]; then |  | ||||||
|    echo "Dirty index: cannot apply patches (dirty: $files)" >&2 |  | ||||||
|    exit 1 |  | ||||||
| fi |  | ||||||
|  |  | ||||||
| usage () { | usage () { | ||||||
|     echo >&2 "usage: $0 [--signoff] [--dotest=<dir>] [--utf8] [--3way] <mbox>" |     echo >&2 "usage: $0 [--signoff] [--dotest=<dir>] [--utf8] [--3way] <mbox>" | ||||||
|     echo >&2 "	or, when resuming" |     echo >&2 "	or, when resuming" | ||||||
|     echo >&2 "	$0 [--skip]" |     echo >&2 "	$0 [--skip | --resolved]" | ||||||
|     exit 1; |     exit 1; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -104,7 +98,7 @@ fall_back_3way () { | ||||||
| } | } | ||||||
|  |  | ||||||
| prec=4 | prec=4 | ||||||
| dotest=.dotest sign= utf8= keep= skip= interactive= | dotest=.dotest sign= utf8= keep= skip= interactive= resolved= | ||||||
|  |  | ||||||
| while case "$#" in 0) break;; esac | while case "$#" in 0) break;; esac | ||||||
| do | do | ||||||
|  | @ -128,6 +122,9 @@ do | ||||||
| 	-k|--k|--ke|--kee|--keep) | 	-k|--k|--ke|--kee|--keep) | ||||||
| 	keep=t; shift ;; | 	keep=t; shift ;; | ||||||
|  |  | ||||||
|  | 	-r|--r|--re|--res|--reso|--resol|--resolv|--resolve|--resolved) | ||||||
|  | 	resolved=t; shift ;; | ||||||
|  |  | ||||||
| 	--sk|--ski|--skip) | 	--sk|--ski|--skip) | ||||||
| 	skip=t; shift ;; | 	skip=t; shift ;; | ||||||
|  |  | ||||||
|  | @ -140,6 +137,8 @@ do | ||||||
| 	esac | 	esac | ||||||
| done | done | ||||||
|  |  | ||||||
|  | # If the dotest directory exists, but we have finished applying all the | ||||||
|  | # patches in them, clear it out. | ||||||
| if test -d "$dotest" && | if test -d "$dotest" && | ||||||
|    last=$(cat "$dotest/last") && |    last=$(cat "$dotest/last") && | ||||||
|    next=$(cat "$dotest/next") && |    next=$(cat "$dotest/next") && | ||||||
|  | @ -155,9 +154,9 @@ then | ||||||
| 	die "previous dotest directory $dotest still exists but mbox given." | 	die "previous dotest directory $dotest still exists but mbox given." | ||||||
| 	resume=yes | 	resume=yes | ||||||
| else | else | ||||||
| 	# Make sure we are not given --skip | 	# Make sure we are not given --skip nor --resolved | ||||||
| 	test ",$skip," = ,, || | 	test ",$skip,$resolved," = ,,, || | ||||||
| 	die "we are not resuming." | 		die "we are not resuming." | ||||||
|  |  | ||||||
| 	# Start afresh. | 	# Start afresh. | ||||||
| 	mkdir -p "$dotest" || exit | 	mkdir -p "$dotest" || exit | ||||||
|  | @ -170,12 +169,24 @@ else | ||||||
| 		exit 1 | 		exit 1 | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	# -s, -u and -k flags are kept for the resuming session after | ||||||
|  | 	# a patch failure. | ||||||
|  | 	# -3 and -i can and must be given when resuming. | ||||||
| 	echo "$sign" >"$dotest/sign" | 	echo "$sign" >"$dotest/sign" | ||||||
| 	echo "$utf8" >"$dotest/utf8" | 	echo "$utf8" >"$dotest/utf8" | ||||||
| 	echo "$keep" >"$dotest/keep" | 	echo "$keep" >"$dotest/keep" | ||||||
| 	echo 1 >"$dotest/next" | 	echo 1 >"$dotest/next" | ||||||
| fi | fi | ||||||
|  |  | ||||||
|  | case "$resolved" in | ||||||
|  | '') | ||||||
|  | 	files=$(git-diff-index --cached --name-only HEAD) || exit | ||||||
|  | 	if [ "$files" ]; then | ||||||
|  | 	   echo "Dirty index: cannot apply patches (dirty: $files)" >&2 | ||||||
|  | 	   exit 1 | ||||||
|  | 	fi | ||||||
|  | esac | ||||||
|  |  | ||||||
| if test "$(cat "$dotest/utf8")" = t | if test "$(cat "$dotest/utf8")" = t | ||||||
| then | then | ||||||
| 	utf8=-u | 	utf8=-u | ||||||
|  | @ -216,6 +227,15 @@ do | ||||||
| 		go_next | 		go_next | ||||||
| 		continue | 		continue | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	# If we are not resuming, parse and extract the patch information | ||||||
|  | 	# into separate files: | ||||||
|  | 	#  - info records the authorship and title | ||||||
|  | 	#  - msg is the rest of commit log message | ||||||
|  | 	#  - patch is the patch body. | ||||||
|  | 	# | ||||||
|  | 	# When we are resuming, these files are either already prepared | ||||||
|  | 	# by the user, or the user can tell us to do so by --resolved flag. | ||||||
| 	case "$resume" in | 	case "$resume" in | ||||||
| 	'') | 	'') | ||||||
| 		git-mailinfo $keep $utf8 "$dotest/msg" "$dotest/patch" \ | 		git-mailinfo $keep $utf8 "$dotest/msg" "$dotest/patch" \ | ||||||
|  | @ -263,6 +283,13 @@ do | ||||||
| 		fi | 		fi | ||||||
| 	    } >"$dotest/final-commit" | 	    } >"$dotest/final-commit" | ||||||
| 	    ;; | 	    ;; | ||||||
|  | 	*) | ||||||
|  | 		case "$resolved,$interactive" in | ||||||
|  | 		tt) | ||||||
|  | 			# This is used only for interactive view option. | ||||||
|  | 			git-diff-index -p --cached HEAD >"$dotest/patch" | ||||||
|  | 			;; | ||||||
|  | 		esac | ||||||
| 	esac | 	esac | ||||||
|  |  | ||||||
| 	resume= | 	resume= | ||||||
|  | @ -310,7 +337,21 @@ do | ||||||
| 	echo "Applying '$SUBJECT'" | 	echo "Applying '$SUBJECT'" | ||||||
| 	echo | 	echo | ||||||
|  |  | ||||||
| 	git-apply --index "$dotest/patch"; apply_status=$? | 	case "$resolved" in | ||||||
|  | 	'') | ||||||
|  | 		git-apply --index "$dotest/patch" | ||||||
|  | 		apply_status=$? | ||||||
|  | 		;; | ||||||
|  | 	t) | ||||||
|  | 		# Resolved means the user did all the hard work, and | ||||||
|  | 		# we do not have to do any patch application.  Just | ||||||
|  | 		# trust what the user has in the index file and the | ||||||
|  | 		# working tree. | ||||||
|  | 		resolved= | ||||||
|  | 		apply_status=0 | ||||||
|  | 		;; | ||||||
|  | 	esac | ||||||
|  |  | ||||||
| 	if test $apply_status = 1 && test "$threeway" = t | 	if test $apply_status = 1 && test "$threeway" = t | ||||||
| 	then | 	then | ||||||
| 		if (fall_back_3way) | 		if (fall_back_3way) | ||||||
|  |  | ||||||
|  | @ -410,8 +410,7 @@ foreach my $ps (@psets) { | ||||||
|     open  HEAD, ">$git_dir/refs/heads/$ps->{branch}"; |     open  HEAD, ">$git_dir/refs/heads/$ps->{branch}"; | ||||||
|     print HEAD $commitid; |     print HEAD $commitid; | ||||||
|     close HEAD; |     close HEAD; | ||||||
|     unlink ("$git_dir/HEAD"); |     system('git-update-ref', 'HEAD', "$ps->{branch}"); | ||||||
|     symlink("refs/heads/$ps->{branch}","$git_dir/HEAD"); |  | ||||||
|  |  | ||||||
|     # tag accordingly |     # tag accordingly | ||||||
|     ptag($ps->{id}, $commitid); # private tag |     ptag($ps->{id}, $commitid); # private tag | ||||||
|  |  | ||||||
|  | @ -4,6 +4,7 @@ use strict; | ||||||
| use Getopt::Std; | use Getopt::Std; | ||||||
| use File::Temp qw(tempdir); | use File::Temp qw(tempdir); | ||||||
| use Data::Dumper; | use Data::Dumper; | ||||||
|  | use File::Basename qw(basename); | ||||||
|  |  | ||||||
| unless ($ENV{GIT_DIR} && -r $ENV{GIT_DIR}){ | unless ($ENV{GIT_DIR} && -r $ENV{GIT_DIR}){ | ||||||
|     die "GIT_DIR is not defined or is unreadable"; |     die "GIT_DIR is not defined or is unreadable"; | ||||||
|  | @ -11,7 +12,7 @@ unless ($ENV{GIT_DIR} && -r $ENV{GIT_DIR}){ | ||||||
|  |  | ||||||
| our ($opt_h, $opt_p, $opt_v, $opt_c ); | our ($opt_h, $opt_p, $opt_v, $opt_c ); | ||||||
|  |  | ||||||
| getopt('hpvc'); | getopts('hpvc'); | ||||||
|  |  | ||||||
| $opt_h && usage(); | $opt_h && usage(); | ||||||
|  |  | ||||||
|  | @ -77,7 +78,7 @@ $opt_v && print "Applying to CVS commit $commit from parent $parent\n"; | ||||||
|  |  | ||||||
| # grab the commit message | # grab the commit message | ||||||
| `git-cat-file commit $commit | sed -e '1,/^\$/d' > .msg`; | `git-cat-file commit $commit | sed -e '1,/^\$/d' > .msg`; | ||||||
| $? && die "Error extraction the commit message"; | $? && die "Error extracting the commit message"; | ||||||
|  |  | ||||||
| my (@afiles, @dfiles, @mfiles); | my (@afiles, @dfiles, @mfiles); | ||||||
| my @files = `git-diff-tree -r $parent $commit`; | my @files = `git-diff-tree -r $parent $commit`; | ||||||
|  | @ -187,9 +188,9 @@ my $cmd = "cvs commit -F .msg $commitfiles"; | ||||||
|  |  | ||||||
| if ($dirtypatch) { | if ($dirtypatch) { | ||||||
|     print "NOTE: One or more hunks failed to apply cleanly.\n"; |     print "NOTE: One or more hunks failed to apply cleanly.\n"; | ||||||
|     print "Resolve the conflicts and then commit using:n"; |     print "Resolve the conflicts and then commit using:\n"; | ||||||
|     print "\n    $cmd\n\n"; |     print "\n    $cmd\n\n"; | ||||||
|     exit; |     exit(1); | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | @ -206,8 +207,7 @@ if ($opt_c) { | ||||||
| } | } | ||||||
| sub usage { | sub usage { | ||||||
| 	print STDERR <<END; | 	print STDERR <<END; | ||||||
| Usage: GIT_DIR=/path/to/.gi ${\basename $0}      # fetch/update GIT from CVS | Usage: GIT_DIR=/path/to/.git ${\basename $0} [-h] [-p] [-v] [-c] [ parent ] commit | ||||||
|        [-h] [-p] [ parent ] commit |  | ||||||
| END | END | ||||||
| 	exit(1); | 	exit(1); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -437,7 +437,11 @@ unless(-d $git_dir) { | ||||||
| 		       "Either use the correct '-o branch' option,\n". | 		       "Either use the correct '-o branch' option,\n". | ||||||
| 		       "or import to a new repository.\n"; | 		       "or import to a new repository.\n"; | ||||||
|  |  | ||||||
| 	$last_branch = basename(readlink("$git_dir/HEAD")); | 	open(F, "git-symbolic-ref HEAD |") or | ||||||
|  | 		die "Cannot run git-symbolic-ref: $!\n"; | ||||||
|  | 	chomp ($last_branch = <F>); | ||||||
|  | 	$last_branch = basename($last_branch); | ||||||
|  | 	close(F); | ||||||
| 	unless($last_branch) { | 	unless($last_branch) { | ||||||
| 		warn "Cannot read the last branch name: $! -- assuming 'master'\n"; | 		warn "Cannot read the last branch name: $! -- assuming 'master'\n"; | ||||||
| 		$last_branch = "master"; | 		$last_branch = "master"; | ||||||
|  | @ -829,8 +833,7 @@ if($orig_branch) { | ||||||
| 	print "DONE; creating $orig_branch branch\n" if $opt_v; | 	print "DONE; creating $orig_branch branch\n" if $opt_v; | ||||||
| 	system("cp","$git_dir/refs/heads/$opt_o","$git_dir/refs/heads/master") | 	system("cp","$git_dir/refs/heads/$opt_o","$git_dir/refs/heads/master") | ||||||
| 		unless -f "$git_dir/refs/heads/master"; | 		unless -f "$git_dir/refs/heads/master"; | ||||||
| 	unlink("$git_dir/HEAD"); | 	system('git-update-ref', 'HEAD', "$orig_branch"); | ||||||
| 	symlink("refs/heads/$orig_branch","$git_dir/HEAD"); |  | ||||||
| 	unless ($opt_i) { | 	unless ($opt_i) { | ||||||
| 		system('git checkout'); | 		system('git checkout'); | ||||||
| 		die "checkout failed: $?\n" if $?; | 		die "checkout failed: $?\n" if $?; | ||||||
|  |  | ||||||
|  | @ -39,5 +39,9 @@ while : ; do | ||||||
| 	esac | 	esac | ||||||
| 	shift | 	shift | ||||||
| done | done | ||||||
|  | [ "$pattern" ] || { | ||||||
|  | 	echo >&2 "usage: 'git grep <pattern> [pathspec*]'" | ||||||
|  | 	exit 1 | ||||||
|  | } | ||||||
| git-ls-files -z "${git_flags[@]}" "$@" | | git-ls-files -z "${git_flags[@]}" "$@" | | ||||||
| 	xargs -0 grep "${flags[@]}" -e "$pattern" | 	xargs -0 grep "${flags[@]}" -e "$pattern" | ||||||
|  |  | ||||||
|  | @ -3,11 +3,13 @@ | ||||||
| # Copyright (C) 2005 Fredrik Kuivinen | # Copyright (C) 2005 Fredrik Kuivinen | ||||||
| # | # | ||||||
|  |  | ||||||
| import sys, math, random, os, re, signal, tempfile, stat, errno, traceback | import sys | ||||||
|  | sys.path.append('''@@GIT_PYTHON_PATH@@''') | ||||||
|  |  | ||||||
|  | import math, random, os, re, signal, tempfile, stat, errno, traceback | ||||||
| from heapq import heappush, heappop | from heapq import heappush, heappop | ||||||
| from sets import Set | from sets import Set | ||||||
|  |  | ||||||
| sys.path.append('''@@GIT_PYTHON_PATH@@''') |  | ||||||
| from gitMergeCommon import * | from gitMergeCommon import * | ||||||
|  |  | ||||||
| outputIndent = 0 | outputIndent = 0 | ||||||
|  |  | ||||||
|  | @ -216,7 +216,11 @@ unless(-d $git_dir) { | ||||||
| 	-f "$git_dir/svn2git" | 	-f "$git_dir/svn2git" | ||||||
| 		or die "'$git_dir/svn2git' does not exist.\n". | 		or die "'$git_dir/svn2git' does not exist.\n". | ||||||
| 		       "You need that file for incremental imports.\n"; | 		       "You need that file for incremental imports.\n"; | ||||||
| 	$last_branch = basename(readlink("$git_dir/HEAD")); | 	open(F, "git-symbolic-ref HEAD |") or | ||||||
|  | 		die "Cannot run git-symbolic-ref: $!\n"; | ||||||
|  | 	chomp ($last_branch = <F>); | ||||||
|  | 	$last_branch = basename($last_branch); | ||||||
|  | 	close(F); | ||||||
| 	unless($last_branch) { | 	unless($last_branch) { | ||||||
| 		warn "Cannot read the last branch name: $! -- assuming 'master'\n"; | 		warn "Cannot read the last branch name: $! -- assuming 'master'\n"; | ||||||
| 		$last_branch = "master"; | 		$last_branch = "master"; | ||||||
|  | @ -766,8 +770,7 @@ if($orig_branch) { | ||||||
| 	print "DONE; creating $orig_branch branch\n" if $opt_v and (not defined $opt_l or $opt_l > 0); | 	print "DONE; creating $orig_branch branch\n" if $opt_v and (not defined $opt_l or $opt_l > 0); | ||||||
| 	system("cp","$git_dir/refs/heads/$opt_o","$git_dir/refs/heads/master") | 	system("cp","$git_dir/refs/heads/$opt_o","$git_dir/refs/heads/master") | ||||||
| 		unless -f "$git_dir/refs/heads/master"; | 		unless -f "$git_dir/refs/heads/master"; | ||||||
| 	unlink("$git_dir/HEAD"); | 	system('git-update-ref', 'HEAD', "$orig_branch"); | ||||||
| 	symlink("refs/heads/$orig_branch","$git_dir/HEAD"); |  | ||||||
| 	unless ($opt_i) { | 	unless ($opt_i) { | ||||||
| 		system('git checkout'); | 		system('git checkout'); | ||||||
| 		die "checkout failed: $?\n" if $?; | 		die "checkout failed: $?\n" if $?; | ||||||
|  |  | ||||||
|  | @ -0,0 +1,295 @@ | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <sys/types.h> | ||||||
|  | #include <sys/stat.h> | ||||||
|  | #include <dirent.h> | ||||||
|  | #include <unistd.h> | ||||||
|  | #include <stdlib.h> | ||||||
|  | #include <string.h> | ||||||
|  | #include <errno.h> | ||||||
|  | #include <limits.h> | ||||||
|  | #include <stdarg.h> | ||||||
|  |  | ||||||
|  | #ifndef PATH_MAX | ||||||
|  | # define PATH_MAX 4096 | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | static const char git_usage[] = | ||||||
|  | 	"Usage: git [--version] [--exec-path[=GIT_EXEC_PATH]] [--help] COMMAND [ ARGS ]"; | ||||||
|  |  | ||||||
|  | /* most gui terms set COLUMNS (although some don't export it) */ | ||||||
|  | static int term_columns(void) | ||||||
|  | { | ||||||
|  | 	char *col_string = getenv("COLUMNS"); | ||||||
|  | 	int n_cols = 0; | ||||||
|  |  | ||||||
|  | 	if (col_string && (n_cols = atoi(col_string)) > 0) | ||||||
|  | 		return n_cols; | ||||||
|  |  | ||||||
|  | 	return 80; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void oom(void) | ||||||
|  | { | ||||||
|  | 	fprintf(stderr, "git: out of memory\n"); | ||||||
|  | 	exit(1); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static inline void mput_char(char c, unsigned int num) | ||||||
|  | { | ||||||
|  | 	while(num--) | ||||||
|  | 		putchar(c); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static struct cmdname { | ||||||
|  | 	size_t len; | ||||||
|  | 	char name[1]; | ||||||
|  | } **cmdname; | ||||||
|  | static int cmdname_alloc, cmdname_cnt; | ||||||
|  |  | ||||||
|  | static void add_cmdname(const char *name, int len) | ||||||
|  | { | ||||||
|  | 	struct cmdname *ent; | ||||||
|  | 	if (cmdname_alloc <= cmdname_cnt) { | ||||||
|  | 		cmdname_alloc = cmdname_alloc + 200; | ||||||
|  | 		cmdname = realloc(cmdname, cmdname_alloc * sizeof(*cmdname)); | ||||||
|  | 		if (!cmdname) | ||||||
|  | 			oom(); | ||||||
|  | 	} | ||||||
|  | 	ent = malloc(sizeof(*ent) + len); | ||||||
|  | 	if (!ent) | ||||||
|  | 		oom(); | ||||||
|  | 	ent->len = len; | ||||||
|  | 	memcpy(ent->name, name, len+1); | ||||||
|  | 	cmdname[cmdname_cnt++] = ent; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static int cmdname_compare(const void *a_, const void *b_) | ||||||
|  | { | ||||||
|  | 	struct cmdname *a = *(struct cmdname **)a_; | ||||||
|  | 	struct cmdname *b = *(struct cmdname **)b_; | ||||||
|  | 	return strcmp(a->name, b->name); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void pretty_print_string_list(struct cmdname **cmdname, int longest) | ||||||
|  | { | ||||||
|  | 	int cols = 1; | ||||||
|  | 	int space = longest + 1; /* min 1 SP between words */ | ||||||
|  | 	int max_cols = term_columns() - 1; /* don't print *on* the edge */ | ||||||
|  | 	int i; | ||||||
|  |  | ||||||
|  | 	if (space < max_cols) | ||||||
|  | 		cols = max_cols / space; | ||||||
|  |  | ||||||
|  | 	qsort(cmdname, cmdname_cnt, sizeof(*cmdname), cmdname_compare); | ||||||
|  |  | ||||||
|  | 	for (i = 0; i < cmdname_cnt; ) { | ||||||
|  | 		int c; | ||||||
|  | 		printf("  "); | ||||||
|  |  | ||||||
|  | 		for (c = cols; c && i < cmdname_cnt; i++) { | ||||||
|  | 			printf("%s", cmdname[i]->name); | ||||||
|  |  | ||||||
|  | 			if (--c) | ||||||
|  | 				mput_char(' ', space - cmdname[i]->len); | ||||||
|  | 		} | ||||||
|  | 		putchar('\n'); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void list_commands(const char *exec_path, const char *pattern) | ||||||
|  | { | ||||||
|  | 	unsigned int longest = 0; | ||||||
|  | 	char path[PATH_MAX]; | ||||||
|  | 	int dirlen; | ||||||
|  | 	DIR *dir = opendir(exec_path); | ||||||
|  | 	struct dirent *de; | ||||||
|  |  | ||||||
|  | 	if (!dir) { | ||||||
|  | 		fprintf(stderr, "git: '%s': %s\n", exec_path, strerror(errno)); | ||||||
|  | 		exit(1); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	dirlen = strlen(exec_path); | ||||||
|  | 	if (PATH_MAX - 20 < dirlen) { | ||||||
|  | 		fprintf(stderr, "git: insanely long exec-path '%s'\n", | ||||||
|  | 			exec_path); | ||||||
|  | 		exit(1); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	memcpy(path, exec_path, dirlen); | ||||||
|  | 	path[dirlen++] = '/'; | ||||||
|  |  | ||||||
|  | 	while ((de = readdir(dir)) != NULL) { | ||||||
|  | 		struct stat st; | ||||||
|  | 		int entlen; | ||||||
|  |  | ||||||
|  | 		if (strncmp(de->d_name, "git-", 4)) | ||||||
|  | 			continue; | ||||||
|  | 		strcpy(path+dirlen, de->d_name); | ||||||
|  | 		if (stat(path, &st) || /* stat, not lstat */ | ||||||
|  | 		    !S_ISREG(st.st_mode) || | ||||||
|  | 		    !(st.st_mode & S_IXUSR)) | ||||||
|  | 			continue; | ||||||
|  |  | ||||||
|  | 		entlen = strlen(de->d_name); | ||||||
|  |  | ||||||
|  | 		if (longest < entlen) | ||||||
|  | 			longest = entlen; | ||||||
|  |  | ||||||
|  | 		add_cmdname(de->d_name + 4, entlen-4); | ||||||
|  | 	} | ||||||
|  | 	closedir(dir); | ||||||
|  |  | ||||||
|  | 	printf("git commands available in '%s'\n", exec_path); | ||||||
|  | 	printf("----------------------------"); | ||||||
|  | 	mput_char('-', strlen(exec_path)); | ||||||
|  | 	putchar('\n'); | ||||||
|  | 	pretty_print_string_list(cmdname, longest - 4); | ||||||
|  | 	putchar('\n'); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #ifdef __GNUC__ | ||||||
|  | static void usage(const char *exec_path, const char *fmt, ...) | ||||||
|  | 	__attribute__((__format__(__printf__, 2, 3), __noreturn__)); | ||||||
|  | #endif | ||||||
|  | static void usage(const char *exec_path, const char *fmt, ...) | ||||||
|  | { | ||||||
|  | 	if (fmt) { | ||||||
|  | 		va_list ap; | ||||||
|  |  | ||||||
|  | 		va_start(ap, fmt); | ||||||
|  | 		printf("git: "); | ||||||
|  | 		vprintf(fmt, ap); | ||||||
|  | 		va_end(ap); | ||||||
|  | 		putchar('\n'); | ||||||
|  | 	} | ||||||
|  | 	else | ||||||
|  | 		puts(git_usage); | ||||||
|  |  | ||||||
|  | 	putchar('\n'); | ||||||
|  |  | ||||||
|  | 	if(exec_path) | ||||||
|  | 		list_commands(exec_path, "git-*"); | ||||||
|  |  | ||||||
|  | 	exit(1); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void prepend_to_path(const char *dir, int len) | ||||||
|  | { | ||||||
|  | 	char *path, *old_path = getenv("PATH"); | ||||||
|  | 	int path_len = len; | ||||||
|  |  | ||||||
|  | 	if (!old_path) | ||||||
|  | 		old_path = "/usr/local/bin:/usr/bin:/bin"; | ||||||
|  |  | ||||||
|  | 	path_len = len + strlen(old_path) + 1; | ||||||
|  |  | ||||||
|  | 	path = malloc(path_len + 1); | ||||||
|  | 	path[path_len + 1] = '\0'; | ||||||
|  |  | ||||||
|  | 	memcpy(path, dir, len); | ||||||
|  | 	path[len] = ':'; | ||||||
|  | 	memcpy(path + len + 1, old_path, path_len - len); | ||||||
|  |  | ||||||
|  | 	setenv("PATH", path, 1); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void show_man_page(char *git_cmd) | ||||||
|  | { | ||||||
|  | 	char *page; | ||||||
|  |  | ||||||
|  | 	if (!strncmp(git_cmd, "git", 3)) | ||||||
|  | 		page = git_cmd; | ||||||
|  | 	else { | ||||||
|  | 		int page_len = strlen(git_cmd) + 4; | ||||||
|  |  | ||||||
|  | 		page = malloc(page_len + 1); | ||||||
|  | 		strcpy(page, "git-"); | ||||||
|  | 		strcpy(page + 4, git_cmd); | ||||||
|  | 		page[page_len] = 0; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	execlp("man", "man", page, NULL); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int main(int argc, char **argv, char **envp) | ||||||
|  | { | ||||||
|  | 	char git_command[PATH_MAX + 1]; | ||||||
|  | 	char wd[PATH_MAX + 1]; | ||||||
|  | 	int i, len, show_help = 0; | ||||||
|  | 	char *exec_path = getenv("GIT_EXEC_PATH"); | ||||||
|  |  | ||||||
|  | 	getcwd(wd, PATH_MAX); | ||||||
|  |  | ||||||
|  | 	if (!exec_path) | ||||||
|  | 		exec_path = GIT_EXEC_PATH; | ||||||
|  |  | ||||||
|  | 	for (i = 1; i < argc; i++) { | ||||||
|  | 		char *arg = argv[i]; | ||||||
|  |  | ||||||
|  | 		if (strncmp(arg, "--", 2)) | ||||||
|  | 			break; | ||||||
|  |  | ||||||
|  | 		arg += 2; | ||||||
|  |  | ||||||
|  | 		if (!strncmp(arg, "exec-path", 9)) { | ||||||
|  | 			arg += 9; | ||||||
|  | 			if (*arg == '=') | ||||||
|  | 				exec_path = arg + 1; | ||||||
|  | 			else { | ||||||
|  | 				puts(exec_path); | ||||||
|  | 				exit(0); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		else if (!strcmp(arg, "version")) { | ||||||
|  | 			printf("git version %s\n", GIT_VERSION); | ||||||
|  | 			exit(0); | ||||||
|  | 		} | ||||||
|  | 		else if (!strcmp(arg, "help")) | ||||||
|  | 			show_help = 1; | ||||||
|  | 		else if (!show_help) | ||||||
|  | 			usage(NULL, NULL); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if (i >= argc || show_help) { | ||||||
|  | 		if (i >= argc) | ||||||
|  | 			usage(exec_path, NULL); | ||||||
|  |  | ||||||
|  | 		show_man_page(argv[i]); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if (*exec_path != '/') { | ||||||
|  | 		if (!getcwd(git_command, sizeof(git_command))) { | ||||||
|  | 			fprintf(stderr, | ||||||
|  | 				"git: cannot determine current directory"); | ||||||
|  | 			exit(1); | ||||||
|  | 		} | ||||||
|  | 		len = strlen(git_command); | ||||||
|  |  | ||||||
|  | 		/* Trivial cleanup */ | ||||||
|  | 		while (!strncmp(exec_path, "./", 2)) { | ||||||
|  | 			exec_path += 2; | ||||||
|  | 			while (*exec_path == '/') | ||||||
|  | 				*exec_path++; | ||||||
|  | 		} | ||||||
|  | 		snprintf(git_command + len, sizeof(git_command) - len, | ||||||
|  | 			 "/%s", exec_path); | ||||||
|  | 	} | ||||||
|  | 	else | ||||||
|  | 		strcpy(git_command, exec_path); | ||||||
|  | 	len = strlen(git_command); | ||||||
|  | 	prepend_to_path(git_command, len); | ||||||
|  |  | ||||||
|  | 	strncat(&git_command[len], "/git-", sizeof(git_command) - len); | ||||||
|  | 	len += 5; | ||||||
|  | 	strncat(&git_command[len], argv[i], sizeof(git_command) - len); | ||||||
|  |  | ||||||
|  | 	if (access(git_command, X_OK)) | ||||||
|  | 		usage(exec_path, "'%s' is not a git-command", argv[i]); | ||||||
|  |  | ||||||
|  | 	/* execve() can only ever return if it fails */ | ||||||
|  | 	execve(git_command, &argv[i], envp); | ||||||
|  | 	printf("Failed to run command '%s': %s\n", git_command, strerror(errno)); | ||||||
|  |  | ||||||
|  | 	return 1; | ||||||
|  | } | ||||||
							
								
								
									
										76
									
								
								git.sh
								
								
								
								
							
							
						
						
									
										76
									
								
								git.sh
								
								
								
								
							|  | @ -1,76 +0,0 @@ | ||||||
| #!/bin/sh |  | ||||||
|  |  | ||||||
| cmd= |  | ||||||
| path=$(dirname "$0") |  | ||||||
| case "$#" in |  | ||||||
| 0)	;; |  | ||||||
| *)	cmd="$1" |  | ||||||
| 	shift |  | ||||||
| 	case "$cmd" in |  | ||||||
| 	-v|--v|--ve|--ver|--vers|--versi|--versio|--version) |  | ||||||
| 		echo "git version @@GIT_VERSION@@" |  | ||||||
| 		exit 0 ;; |  | ||||||
| 	esac |  | ||||||
| 	 |  | ||||||
| 	test -x "$path/git-$cmd" && exec "$path/git-$cmd" "$@" |  | ||||||
| 	 |  | ||||||
| 	case '@@X@@' in |  | ||||||
| 	    '') |  | ||||||
| 		;; |  | ||||||
| 	    *) |  | ||||||
| 		test -x "$path/git-$cmd@@X@@" && |  | ||||||
| 		exec "$path/git-$cmd@@X@@" "$@" |  | ||||||
| 		;; |  | ||||||
| 	esac |  | ||||||
| 	;; |  | ||||||
| esac |  | ||||||
|  |  | ||||||
| echo "Usage: git COMMAND [OPTIONS] [TARGET]" |  | ||||||
| if [ -n "$cmd" ]; then |  | ||||||
|     echo "git command '$cmd' not found." |  | ||||||
| fi |  | ||||||
| echo "git commands are:" |  | ||||||
|  |  | ||||||
| fmt <<\EOF | sed -e 's/^/    /' |  | ||||||
| add |  | ||||||
| apply |  | ||||||
| archimport |  | ||||||
| bisect |  | ||||||
| branch |  | ||||||
| checkout |  | ||||||
| cherry |  | ||||||
| clone |  | ||||||
| commit |  | ||||||
| count-objects |  | ||||||
| cvsimport |  | ||||||
| diff |  | ||||||
| fetch |  | ||||||
| format-patch |  | ||||||
| fsck-objects |  | ||||||
| get-tar-commit-id |  | ||||||
| init-db |  | ||||||
| log |  | ||||||
| ls-remote |  | ||||||
| octopus |  | ||||||
| pack-objects |  | ||||||
| parse-remote |  | ||||||
| patch-id |  | ||||||
| prune |  | ||||||
| pull |  | ||||||
| push |  | ||||||
| rebase |  | ||||||
| relink |  | ||||||
| rename |  | ||||||
| repack |  | ||||||
| request-pull |  | ||||||
| reset |  | ||||||
| resolve |  | ||||||
| revert |  | ||||||
| send-email |  | ||||||
| shortlog |  | ||||||
| show-branch |  | ||||||
| status |  | ||||||
| tag |  | ||||||
| verify-tag |  | ||||||
| whatchanged |  | ||||||
| EOF |  | ||||||
|  | @ -1,5 +1,5 @@ | ||||||
| # Pass --without docs to rpmbuild if you don't want the documentation | # Pass --without docs to rpmbuild if you don't want the documentation | ||||||
| Name: 		git-core | Name: 		git | ||||||
| Version: 	@@VERSION@@ | Version: 	@@VERSION@@ | ||||||
| Release: 	1%{?dist} | Release: 	1%{?dist} | ||||||
| Summary:  	Git core and tools | Summary:  	Git core and tools | ||||||
|  | @ -9,7 +9,7 @@ URL: 		http://kernel.org/pub/software/scm/git/ | ||||||
| Source: 	http://kernel.org/pub/software/scm/git/%{name}-%{version}.tar.gz | Source: 	http://kernel.org/pub/software/scm/git/%{name}-%{version}.tar.gz | ||||||
| BuildRequires:	zlib-devel >= 1.2, openssl-devel, curl-devel, expat-devel  %{!?_without_docs:, xmlto, asciidoc > 6.0.3} | BuildRequires:	zlib-devel >= 1.2, openssl-devel, curl-devel, expat-devel  %{!?_without_docs:, xmlto, asciidoc > 6.0.3} | ||||||
| BuildRoot:	%{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) | BuildRoot:	%{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) | ||||||
| Requires:	zlib >= 1.2, rsync, rcs, curl, less, openssh-clients, python >= 2.3, expat | Requires:	git-core, git-svn, git-cvs, git-arch, git-email, gitk | ||||||
|  |  | ||||||
| %description | %description | ||||||
| This is a stupid (but extremely fast) directory content manager.  It | This is a stupid (but extremely fast) directory content manager.  It | ||||||
|  | @ -19,6 +19,22 @@ distributed source code management system. This package includes | ||||||
| rudimentary tools that can be used as a SCM, but you should look | rudimentary tools that can be used as a SCM, but you should look | ||||||
| elsewhere for tools for ordinary humans layered on top of this. | elsewhere for tools for ordinary humans layered on top of this. | ||||||
|  |  | ||||||
|  | This is a dummy package which brings in all subpackages. | ||||||
|  |  | ||||||
|  | %package core | ||||||
|  | Summary:	Core git tools | ||||||
|  | Group:		Development/Tools | ||||||
|  | Requires:	zlib >= 1.2, rsync, rcs, curl, less, openssh-clients, python >= 2.3, expat | ||||||
|  | %description core | ||||||
|  | This is a stupid (but extremely fast) directory content manager.  It | ||||||
|  | doesn't do a whole lot, but what it _does_ do is track directory | ||||||
|  | contents efficiently. It is intended to be the base of an efficient, | ||||||
|  | distributed source code management system. This package includes | ||||||
|  | rudimentary tools that can be used as a SCM, but you should look | ||||||
|  | elsewhere for tools for ordinary humans layered on top of this. | ||||||
|  |  | ||||||
|  | These are the core tools with minimal dependencies. | ||||||
|  |  | ||||||
| %package svn | %package svn | ||||||
| Summary:        Git tools for importing Subversion repositories | Summary:        Git tools for importing Subversion repositories | ||||||
| Group:          Development/Tools | Group:          Development/Tools | ||||||
|  | @ -47,11 +63,11 @@ Requires:	git-core = %{version}-%{release} | ||||||
| %description email | %description email | ||||||
| Git tools for sending email. | Git tools for sending email. | ||||||
|  |  | ||||||
| %package tk | %package -n gitk | ||||||
| Summary:        Git revision tree visualiser ('gitk') | Summary:        Git revision tree visualiser ('gitk') | ||||||
| Group:          Development/Tools | Group:          Development/Tools | ||||||
| Requires:       git-core = %{version}-%{release}, tk >= 8.4 | Requires:       git-core = %{version}-%{release}, tk >= 8.4 | ||||||
| %description tk | %description -n gitk | ||||||
| Git revision tree visualiser ('gitk') | Git revision tree visualiser ('gitk') | ||||||
|  |  | ||||||
| %prep | %prep | ||||||
|  | @ -75,6 +91,9 @@ make %{_smp_mflags} DESTDIR=$RPM_BUILD_ROOT WITH_OWN_SUBPROCESS_PY=YesPlease WIT | ||||||
| %clean | %clean | ||||||
| rm -rf $RPM_BUILD_ROOT | rm -rf $RPM_BUILD_ROOT | ||||||
|  |  | ||||||
|  | %files | ||||||
|  | # These are no files in the root package | ||||||
|  |  | ||||||
| %files svn | %files svn | ||||||
| %defattr(-,root,root) | %defattr(-,root,root) | ||||||
| %{_bindir}/*svn* | %{_bindir}/*svn* | ||||||
|  | @ -103,20 +122,25 @@ rm -rf $RPM_BUILD_ROOT | ||||||
| %{!?_without_docs: %{_mandir}/man1/*email*.1*} | %{!?_without_docs: %{_mandir}/man1/*email*.1*} | ||||||
| %{!?_without_docs: %doc Documentation/*email*.html } | %{!?_without_docs: %doc Documentation/*email*.html } | ||||||
|  |  | ||||||
| %files tk | %files -n gitk | ||||||
| %defattr(-,root,root) | %defattr(-,root,root) | ||||||
| %doc Documentation/*gitk*.txt | %doc Documentation/*gitk*.txt | ||||||
| %{_bindir}/*gitk* | %{_bindir}/*gitk* | ||||||
| %{!?_without_docs: %{_mandir}/man1/*gitk*.1*} | %{!?_without_docs: %{_mandir}/man1/*gitk*.1*} | ||||||
| %{!?_without_docs: %doc Documentation/*gitk*.html } | %{!?_without_docs: %doc Documentation/*gitk*.html } | ||||||
|  |  | ||||||
| %files -f bin-man-doc-files | %files core -f bin-man-doc-files | ||||||
| %defattr(-,root,root) | %defattr(-,root,root) | ||||||
| %{_datadir}/git-core/ | %{_datadir}/git-core/ | ||||||
| %doc README COPYING Documentation/*.txt | %doc README COPYING Documentation/*.txt | ||||||
| %{!?_without_docs: %doc Documentation/*.html } | %{!?_without_docs: %doc Documentation/*.html } | ||||||
|  |  | ||||||
| %changelog | %changelog | ||||||
|  | * Mon Nov 14 2005 H. Peter Anvin <hpa@zytor.com> 0.99.9j-1 | ||||||
|  | - Change subpackage names to git-<name> instead of git-core-<name> | ||||||
|  | - Create empty root package which brings in all subpackages | ||||||
|  | - Rename git-tk -> gitk | ||||||
|  |  | ||||||
| * Thu Nov 10 2005 Chris Wright <chrisw@osdl.org> 0.99.9g-1 | * Thu Nov 10 2005 Chris Wright <chrisw@osdl.org> 0.99.9g-1 | ||||||
| - zlib dependency fix | - zlib dependency fix | ||||||
| - Minor cleanups from split | - Minor cleanups from split | ||||||
							
								
								
									
										16
									
								
								http-fetch.c
								
								
								
								
							
							
						
						
									
										16
									
								
								http-fetch.c
								
								
								
								
							|  | @ -425,6 +425,8 @@ static void start_request(struct transfer_request *request) | ||||||
| 	rename(request->tmpfile, prevfile); | 	rename(request->tmpfile, prevfile); | ||||||
| 	unlink(request->tmpfile); | 	unlink(request->tmpfile); | ||||||
|  |  | ||||||
|  | 	if (request->local != -1) | ||||||
|  | 		error("fd leakage in start: %d", request->local); | ||||||
| 	request->local = open(request->tmpfile, | 	request->local = open(request->tmpfile, | ||||||
| 			      O_WRONLY | O_CREAT | O_EXCL, 0666); | 			      O_WRONLY | O_CREAT | O_EXCL, 0666); | ||||||
| 	/* This could have failed due to the "lazy directory creation"; | 	/* This could have failed due to the "lazy directory creation"; | ||||||
|  | @ -523,7 +525,7 @@ static void start_request(struct transfer_request *request) | ||||||
| 	/* Try to get the request started, abort the request on error */ | 	/* Try to get the request started, abort the request on error */ | ||||||
| 	if (!start_active_slot(slot)) { | 	if (!start_active_slot(slot)) { | ||||||
| 		request->state = ABORTED; | 		request->state = ABORTED; | ||||||
| 		close(request->local); | 		close(request->local); request->local = -1; | ||||||
| 		free(request->url); | 		free(request->url); | ||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
|  | @ -537,7 +539,7 @@ static void finish_request(struct transfer_request *request) | ||||||
| 	struct stat st; | 	struct stat st; | ||||||
|  |  | ||||||
| 	fchmod(request->local, 0444); | 	fchmod(request->local, 0444); | ||||||
| 	close(request->local); | 	close(request->local); request->local = -1; | ||||||
|  |  | ||||||
| 	if (request->http_code == 416) { | 	if (request->http_code == 416) { | ||||||
| 		fprintf(stderr, "Warning: requested range invalid; we may already have all the data.\n"); | 		fprintf(stderr, "Warning: requested range invalid; we may already have all the data.\n"); | ||||||
|  | @ -569,6 +571,8 @@ static void release_request(struct transfer_request *request) | ||||||
| { | { | ||||||
| 	struct transfer_request *entry = request_queue_head; | 	struct transfer_request *entry = request_queue_head; | ||||||
|  |  | ||||||
|  | 	if (request->local != -1) | ||||||
|  | 		error("fd leakage in release: %d", request->local); | ||||||
| 	if (request == request_queue_head) { | 	if (request == request_queue_head) { | ||||||
| 		request_queue_head = request->next; | 		request_queue_head = request->next; | ||||||
| 	} else { | 	} else { | ||||||
|  | @ -631,6 +635,8 @@ static void process_curl_messages(void) | ||||||
| 					if (request->repo->next != NULL) { | 					if (request->repo->next != NULL) { | ||||||
| 						request->repo = | 						request->repo = | ||||||
| 							request->repo->next; | 							request->repo->next; | ||||||
|  | 						close(request->local); | ||||||
|  | 							request->local = -1; | ||||||
| 						start_request(request); | 						start_request(request); | ||||||
| 					} else { | 					} else { | ||||||
| 						finish_request(request); | 						finish_request(request); | ||||||
|  | @ -763,6 +769,7 @@ static int fetch_index(struct alt_base *repo, unsigned char *sha1) | ||||||
| 				     curl_errorstr); | 				     curl_errorstr); | ||||||
| 		} | 		} | ||||||
| 	} else { | 	} else { | ||||||
|  | 		fclose(indexfile); | ||||||
| 		return error("Unable to start request"); | 		return error("Unable to start request"); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -1083,6 +1090,7 @@ static int fetch_pack(struct alt_base *repo, unsigned char *sha1) | ||||||
| 				     curl_errorstr); | 				     curl_errorstr); | ||||||
| 		} | 		} | ||||||
| 	} else { | 	} else { | ||||||
|  | 		fclose(packfile); | ||||||
| 		return error("Unable to start request"); | 		return error("Unable to start request"); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -1145,6 +1153,7 @@ static int fetch_object(struct alt_base *repo, unsigned char *sha1) | ||||||
| 			fetch_alternates(alt->base); | 			fetch_alternates(alt->base); | ||||||
| 			if (request->repo->next != NULL) { | 			if (request->repo->next != NULL) { | ||||||
| 				request->repo = request->repo->next; | 				request->repo = request->repo->next; | ||||||
|  | 				close(request->local); request->local = -1; | ||||||
| 				start_request(request); | 				start_request(request); | ||||||
| 			} | 			} | ||||||
| 		} else { | 		} else { | ||||||
|  | @ -1153,6 +1162,9 @@ static int fetch_object(struct alt_base *repo, unsigned char *sha1) | ||||||
| 		} | 		} | ||||||
| #endif | #endif | ||||||
| 	} | 	} | ||||||
|  | 	if (request->local != -1) { | ||||||
|  | 		close(request->local); request->local = -1; | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	if (request->state == ABORTED) { | 	if (request->state == ABORTED) { | ||||||
| 		release_request(request); | 		release_request(request); | ||||||
|  |  | ||||||
							
								
								
									
										64
									
								
								object.c
								
								
								
								
							
							
						
						
									
										64
									
								
								object.c
								
								
								
								
							|  | @ -67,40 +67,66 @@ void created_object(const unsigned char *sha1, struct object *obj) | ||||||
| 	nr_objs++; | 	nr_objs++; | ||||||
| } | } | ||||||
|  |  | ||||||
| void add_ref(struct object *refer, struct object *target) | struct object_refs *alloc_object_refs(unsigned count) | ||||||
| { | { | ||||||
| 	struct object_list **pp, *p; | 	struct object_refs *refs; | ||||||
|  | 	size_t size = sizeof(*refs) + count*sizeof(struct object *); | ||||||
|  |  | ||||||
| 	if (!track_object_refs) | 	refs = xmalloc(size); | ||||||
|  | 	memset(refs, 0, size); | ||||||
|  | 	refs->count = count; | ||||||
|  | 	return refs; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static int compare_object_pointers(const void *a, const void *b) | ||||||
|  | { | ||||||
|  | 	const struct object * const *pa = a; | ||||||
|  | 	const struct object * const *pb = b; | ||||||
|  | 	return *pa - *pb; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void set_object_refs(struct object *obj, struct object_refs *refs) | ||||||
|  | { | ||||||
|  | 	unsigned int i, j; | ||||||
|  |  | ||||||
|  | 	/* Do not install empty list of references */ | ||||||
|  | 	if (refs->count < 1) { | ||||||
|  | 		free(refs); | ||||||
| 		return; | 		return; | ||||||
|  |  | ||||||
| 	pp = &refer->refs; |  | ||||||
| 	while ((p = *pp) != NULL) { |  | ||||||
| 		if (p->item == target) |  | ||||||
| 			return; |  | ||||||
| 		pp = &p->next; |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	target->used = 1; | 	/* Sort the list and filter out duplicates */ | ||||||
| 	p = xmalloc(sizeof(*p)); | 	qsort(refs->ref, refs->count, sizeof(refs->ref[0]), | ||||||
| 	p->item = target; | 	      compare_object_pointers); | ||||||
| 	p->next = NULL; | 	for (i = j = 1; i < refs->count; i++) { | ||||||
| 	*pp = p; | 		if (refs->ref[i] != refs->ref[i - 1]) | ||||||
|  | 			refs->ref[j++] = refs->ref[i]; | ||||||
|  | 	} | ||||||
|  | 	if (j < refs->count) { | ||||||
|  | 		/* Duplicates were found - reallocate list */ | ||||||
|  | 		size_t size = sizeof(*refs) + j*sizeof(struct object *); | ||||||
|  | 		refs->count = j; | ||||||
|  | 		refs = xrealloc(refs, size); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	for (i = 0; i < refs->count; i++) | ||||||
|  | 		refs->ref[i]->used = 1; | ||||||
|  | 	obj->refs = refs; | ||||||
| } | } | ||||||
|  |  | ||||||
| void mark_reachable(struct object *obj, unsigned int mask) | void mark_reachable(struct object *obj, unsigned int mask) | ||||||
| { | { | ||||||
| 	struct object_list *p = obj->refs; |  | ||||||
|  |  | ||||||
| 	if (!track_object_refs) | 	if (!track_object_refs) | ||||||
| 		die("cannot do reachability with object refs turned off"); | 		die("cannot do reachability with object refs turned off"); | ||||||
| 	/* If we've been here already, don't bother */ | 	/* If we've been here already, don't bother */ | ||||||
| 	if (obj->flags & mask) | 	if (obj->flags & mask) | ||||||
| 		return; | 		return; | ||||||
| 	obj->flags |= mask; | 	obj->flags |= mask; | ||||||
| 	while (p) { | 	if (obj->refs) { | ||||||
| 		mark_reachable(p->item, mask); | 		const struct object_refs *refs = obj->refs; | ||||||
| 		p = p->next; | 		unsigned i; | ||||||
|  | 		for (i = 0; i < refs->count; i++) | ||||||
|  | 			mark_reachable(refs->ref[i], mask); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
							
								
								
									
										10
									
								
								object.h
								
								
								
								
							
							
						
						
									
										10
									
								
								object.h
								
								
								
								
							|  | @ -7,13 +7,18 @@ struct object_list { | ||||||
| 	const char *name; | 	const char *name; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | struct object_refs { | ||||||
|  | 	unsigned count; | ||||||
|  | 	struct object *ref[0]; | ||||||
|  | }; | ||||||
|  |  | ||||||
| struct object { | struct object { | ||||||
| 	unsigned parsed : 1; | 	unsigned parsed : 1; | ||||||
| 	unsigned used : 1; | 	unsigned used : 1; | ||||||
| 	unsigned int flags; | 	unsigned int flags; | ||||||
| 	unsigned char sha1[20]; | 	unsigned char sha1[20]; | ||||||
| 	const char *type; | 	const char *type; | ||||||
| 	struct object_list *refs; | 	struct object_refs *refs; | ||||||
| 	void *util; | 	void *util; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | @ -35,7 +40,8 @@ struct object *parse_object(const unsigned char *sha1); | ||||||
| /** Returns the object, with potentially excess memory allocated. **/ | /** Returns the object, with potentially excess memory allocated. **/ | ||||||
| struct object *lookup_unknown_object(const unsigned  char *sha1); | struct object *lookup_unknown_object(const unsigned  char *sha1); | ||||||
|  |  | ||||||
| void add_ref(struct object *refer, struct object *target); | struct object_refs *alloc_object_refs(unsigned count); | ||||||
|  | void set_object_refs(struct object *obj, struct object_refs *refs); | ||||||
|  |  | ||||||
| void mark_reachable(struct object *obj, unsigned int mask); | void mark_reachable(struct object *obj, unsigned int mask); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | @ -127,38 +127,6 @@ inline struct llist_item * llist_insert_sorted_unique(struct llist *list, | ||||||
| 	return llist_insert_back(list, sha1); | 	return llist_insert_back(list, sha1); | ||||||
| } | } | ||||||
|  |  | ||||||
| /* computes A\B */ |  | ||||||
| void llist_sorted_difference_inplace(struct llist *A, |  | ||||||
| 				     struct llist *B) |  | ||||||
| { |  | ||||||
| 	struct llist_item *prev, *a, *b, *x; |  | ||||||
|  |  | ||||||
| 	prev = a = A->front; |  | ||||||
| 	b = B->front; |  | ||||||
|  |  | ||||||
| 	while (a != NULL && b != NULL) { |  | ||||||
| 		int cmp = memcmp(a->sha1, b->sha1, 20); |  | ||||||
| 		if (!cmp) { |  | ||||||
| 			x = a; |  | ||||||
| 			if (a == A->front) |  | ||||||
| 				A->front = a->next; |  | ||||||
| 			a = prev->next = a->next; |  | ||||||
|  |  | ||||||
| 			if (a == NULL) /* end of list */ |  | ||||||
| 				A->back = prev; |  | ||||||
| 			A->size--; |  | ||||||
| 			free(x); |  | ||||||
| 			b = b->next; |  | ||||||
| 		} else |  | ||||||
| 			if (cmp > 0) |  | ||||||
| 				b = b->next; |  | ||||||
| 			else { |  | ||||||
| 				prev = a; |  | ||||||
| 				a = a->next; |  | ||||||
| 			} |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /* returns a pointer to an item in front of sha1 */ | /* returns a pointer to an item in front of sha1 */ | ||||||
| inline struct llist_item * llist_sorted_remove(struct llist *list, char *sha1, | inline struct llist_item * llist_sorted_remove(struct llist *list, char *sha1, | ||||||
| 					       struct llist_item *hint) | 					       struct llist_item *hint) | ||||||
|  | @ -194,6 +162,21 @@ redo_from_start: | ||||||
| 	return prev; | 	return prev; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /* computes A\B */ | ||||||
|  | void llist_sorted_difference_inplace(struct llist *A, | ||||||
|  | 				     struct llist *B) | ||||||
|  | { | ||||||
|  | 	struct llist_item *hint, *b; | ||||||
|  |  | ||||||
|  | 	hint = NULL; | ||||||
|  | 	b = B->front; | ||||||
|  |  | ||||||
|  | 	while (b) { | ||||||
|  | 		hint = llist_sorted_remove(A, b->sha1, hint); | ||||||
|  | 		b = b->next; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
| inline struct pack_list * pack_list_insert(struct pack_list **pl, | inline struct pack_list * pack_list_insert(struct pack_list **pl, | ||||||
| 					   struct pack_list *entry) | 					   struct pack_list *entry) | ||||||
| { | { | ||||||
|  |  | ||||||
							
								
								
									
										10
									
								
								refs.c
								
								
								
								
							
							
						
						
									
										10
									
								
								refs.c
								
								
								
								
							|  | @ -121,10 +121,12 @@ int create_symref(const char *git_HEAD, const char *refs_heads_master) | ||||||
| 	int fd, len, written; | 	int fd, len, written; | ||||||
|  |  | ||||||
| #if USE_SYMLINK_HEAD | #if USE_SYMLINK_HEAD | ||||||
| 	unlink(git_HEAD); | 	if (!only_use_symrefs) { | ||||||
| 	if (!symlink(refs_heads_master, git_HEAD)) | 		unlink(git_HEAD); | ||||||
| 		return 0; | 		if (!symlink(refs_heads_master, git_HEAD)) | ||||||
| 	fprintf(stderr, "no symlink - falling back to symbolic ref\n"); | 			return 0; | ||||||
|  | 		fprintf(stderr, "no symlink - falling back to symbolic ref\n"); | ||||||
|  | 	} | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| 	len = snprintf(ref, sizeof(ref), "ref: %s\n", refs_heads_master); | 	len = snprintf(ref, sizeof(ref), "ref: %s\n", refs_heads_master); | ||||||
|  |  | ||||||
|  | @ -424,7 +424,6 @@ static void find_pack_info_one(int pack_ix) | ||||||
| { | { | ||||||
| 	unsigned char sha1[20]; | 	unsigned char sha1[20]; | ||||||
| 	struct object *o; | 	struct object *o; | ||||||
| 	struct object_list *ref; |  | ||||||
| 	int i; | 	int i; | ||||||
| 	struct packed_git *p = info[pack_ix]->p; | 	struct packed_git *p = info[pack_ix]->p; | ||||||
| 	int num = num_packed_objects(p); | 	int num = num_packed_objects(p); | ||||||
|  | @ -437,8 +436,12 @@ static void find_pack_info_one(int pack_ix) | ||||||
| 			die("corrupt pack file %s?", p->pack_name); | 			die("corrupt pack file %s?", p->pack_name); | ||||||
| 		if ((o = lookup_object(sha1)) == NULL) | 		if ((o = lookup_object(sha1)) == NULL) | ||||||
| 			die("cannot parse %s", sha1_to_hex(sha1)); | 			die("cannot parse %s", sha1_to_hex(sha1)); | ||||||
| 		for (ref = o->refs; ref; ref = ref->next) | 		if (o->refs) { | ||||||
| 			ref->item->flags = 0; | 			struct object_refs *refs = o->refs; | ||||||
|  | 			int j; | ||||||
|  | 			for (j = 0; j < refs->count; j++) | ||||||
|  | 				refs->ref[j]->flags = 0; | ||||||
|  | 		} | ||||||
| 		o->flags = 0; | 		o->flags = 0; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -448,8 +451,12 @@ static void find_pack_info_one(int pack_ix) | ||||||
| 			die("corrupt pack file %s?", p->pack_name); | 			die("corrupt pack file %s?", p->pack_name); | ||||||
| 		if ((o = lookup_object(sha1)) == NULL) | 		if ((o = lookup_object(sha1)) == NULL) | ||||||
| 			die("cannot find %s", sha1_to_hex(sha1)); | 			die("cannot find %s", sha1_to_hex(sha1)); | ||||||
| 		for (ref = o->refs; ref; ref = ref->next) | 		if (o->refs) { | ||||||
| 			ref->item->flags |= REFERENCED; | 			struct object_refs *refs = o->refs; | ||||||
|  | 			int j; | ||||||
|  | 			for (j = 0; j < refs->count; j++) | ||||||
|  | 				refs->ref[j]->flags |= REFERENCED; | ||||||
|  | 		} | ||||||
| 		o->flags |= INTERNAL; | 		o->flags |= INTERNAL; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -460,8 +467,12 @@ static void find_pack_info_one(int pack_ix) | ||||||
| 			die("cannot find %s", sha1_to_hex(sha1)); | 			die("cannot find %s", sha1_to_hex(sha1)); | ||||||
|  |  | ||||||
| 		show(o, pack_ix); | 		show(o, pack_ix); | ||||||
| 		for (ref = o->refs; ref; ref = ref->next) | 		if (o->refs) { | ||||||
| 			show(ref->item, pack_ix); | 			struct object_refs *refs = o->refs; | ||||||
|  | 			int j; | ||||||
|  | 			for (j = 0; j < refs->count; j++) | ||||||
|  | 				show(refs->ref[j], pack_ix); | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -424,7 +424,7 @@ struct packed_git *add_packed_git(char *path, int path_len, int local) | ||||||
| 	struct packed_git *p; | 	struct packed_git *p; | ||||||
| 	unsigned long idx_size; | 	unsigned long idx_size; | ||||||
| 	void *idx_map; | 	void *idx_map; | ||||||
| 	char sha1[20]; | 	unsigned char sha1[20]; | ||||||
|  |  | ||||||
| 	if (check_packed_git_idx(path, &idx_size, &idx_map)) | 	if (check_packed_git_idx(path, &idx_size, &idx_map)) | ||||||
| 		return NULL; | 		return NULL; | ||||||
|  |  | ||||||
|  | @ -20,6 +20,7 @@ static void check_symref(const char *HEAD) | ||||||
| int main(int argc, const char **argv) | int main(int argc, const char **argv) | ||||||
| { | { | ||||||
| 	setup_git_directory(); | 	setup_git_directory(); | ||||||
|  | 	git_config(git_default_config); | ||||||
| 	switch (argc) { | 	switch (argc) { | ||||||
| 	case 2: | 	case 2: | ||||||
| 		check_symref(argv[1]); | 		check_symref(argv[1]); | ||||||
|  |  | ||||||
|  | @ -0,0 +1,115 @@ | ||||||
|  | #!/bin/sh | ||||||
|  | # | ||||||
|  | # Copyright (c) 2005 Junio C Hamano | ||||||
|  | # | ||||||
|  |  | ||||||
|  | test_description='git-apply handling binary patches | ||||||
|  |  | ||||||
|  | ' | ||||||
|  | . ./test-lib.sh | ||||||
|  |  | ||||||
|  | # setup | ||||||
|  |  | ||||||
|  | cat >file1 <<EOF | ||||||
|  | A quick brown fox jumps over the lazy dog. | ||||||
|  | A tiny little penguin runs around in circles. | ||||||
|  | There is a flag with Linux written on it. | ||||||
|  | A slow black-and-white panda just sits there, | ||||||
|  | munching on his bamboo. | ||||||
|  | EOF | ||||||
|  | cat file1 >file2 | ||||||
|  | cat file1 >file4 | ||||||
|  |  | ||||||
|  | git-update-index --add --remove file1 file2 file4 | ||||||
|  | git-commit -m 'Initial Version' 2>/dev/null | ||||||
|  |  | ||||||
|  | git-checkout -b binary | ||||||
|  | tr 'x' '\0' <file1 >file3 | ||||||
|  | cat file3 >file4 | ||||||
|  | git-add file2 | ||||||
|  | tr '\0' 'v' <file3 >file1 | ||||||
|  | rm -f file2 | ||||||
|  | git-update-index --add --remove file1 file2 file3 file4 | ||||||
|  | git-commit -m 'Second Version' | ||||||
|  |  | ||||||
|  | git-diff-tree -p master binary >B.diff | ||||||
|  | git-diff-tree -p -C master binary >C.diff | ||||||
|  |  | ||||||
|  | git-diff-tree -p --full-index master binary >BF.diff | ||||||
|  | git-diff-tree -p --full-index -C master binary >CF.diff | ||||||
|  |  | ||||||
|  | test_expect_success 'stat binary diff -- should not fail.' \ | ||||||
|  | 	'git-checkout master | ||||||
|  | 	 git-apply --stat --summary B.diff' | ||||||
|  |  | ||||||
|  | test_expect_success 'stat binary diff (copy) -- should not fail.' \ | ||||||
|  | 	'git-checkout master | ||||||
|  | 	 git-apply --stat --summary C.diff' | ||||||
|  |  | ||||||
|  | test_expect_failure 'check binary diff -- should fail.' \ | ||||||
|  | 	'git-checkout master | ||||||
|  | 	 git-apply --check B.diff' | ||||||
|  |  | ||||||
|  | test_expect_failure 'check binary diff (copy) -- should fail.' \ | ||||||
|  | 	'git-checkout master | ||||||
|  | 	 git-apply --check C.diff' | ||||||
|  |  | ||||||
|  | test_expect_failure 'check incomplete binary diff with replacement -- should fail.' \ | ||||||
|  | 	'git-checkout master | ||||||
|  | 	 git-apply --check --allow-binary-replacement B.diff' | ||||||
|  |  | ||||||
|  | test_expect_failure 'check incomplete binary diff with replacement (copy) -- should fail.' \ | ||||||
|  | 	'git-checkout master | ||||||
|  | 	 git-apply --check --allow-binary-replacement C.diff' | ||||||
|  |  | ||||||
|  | test_expect_success 'check binary diff with replacement.' \ | ||||||
|  | 	'git-checkout master | ||||||
|  | 	 git-apply --check --allow-binary-replacement BF.diff' | ||||||
|  |  | ||||||
|  | test_expect_success 'check binary diff with replacement (copy).' \ | ||||||
|  | 	'git-checkout master | ||||||
|  | 	 git-apply --check --allow-binary-replacement CF.diff' | ||||||
|  |  | ||||||
|  | # Now we start applying them. | ||||||
|  |  | ||||||
|  | do_reset () { | ||||||
|  | 	rm -f file? | ||||||
|  | 	git-reset --hard | ||||||
|  | 	git-checkout -f master | ||||||
|  | } | ||||||
|  |  | ||||||
|  | test_expect_failure 'apply binary diff -- should fail.' \ | ||||||
|  | 	'do_reset | ||||||
|  | 	 git-apply B.diff' | ||||||
|  |  | ||||||
|  | test_expect_failure 'apply binary diff -- should fail.' \ | ||||||
|  | 	'do_reset | ||||||
|  | 	 git-apply --index B.diff' | ||||||
|  |  | ||||||
|  | test_expect_failure 'apply binary diff (copy) -- should fail.' \ | ||||||
|  | 	'do_reset | ||||||
|  | 	 git-apply C.diff' | ||||||
|  |  | ||||||
|  | test_expect_failure 'apply binary diff (copy) -- should fail.' \ | ||||||
|  | 	'do_reset | ||||||
|  | 	 git-apply --index C.diff' | ||||||
|  |  | ||||||
|  | test_expect_failure 'apply binary diff without replacement -- should fail.' \ | ||||||
|  | 	'do_reset | ||||||
|  | 	 git-apply BF.diff' | ||||||
|  |  | ||||||
|  | test_expect_failure 'apply binary diff without replacement (copy) -- should fail.' \ | ||||||
|  | 	'do_reset | ||||||
|  | 	 git-apply CF.diff' | ||||||
|  |  | ||||||
|  | test_expect_success 'apply binary diff.' \ | ||||||
|  | 	'do_reset | ||||||
|  | 	 git-apply --allow-binary-replacement --index BF.diff && | ||||||
|  | 	 test -z "$(git-diff --name-status binary)"' | ||||||
|  |  | ||||||
|  | test_expect_success 'apply binary diff (copy).' \ | ||||||
|  | 	'do_reset | ||||||
|  | 	 git-apply --allow-binary-replacement --index CF.diff && | ||||||
|  | 	 test -z "$(git-diff --name-status binary)"' | ||||||
|  |  | ||||||
|  | test_done | ||||||
|  | @ -158,6 +158,8 @@ test_done () { | ||||||
| # Test the binaries we have just built.  The tests are kept in | # Test the binaries we have just built.  The tests are kept in | ||||||
| # t/ subdirectory and are run in trash subdirectory. | # t/ subdirectory and are run in trash subdirectory. | ||||||
| PATH=$(pwd)/..:$PATH | PATH=$(pwd)/..:$PATH | ||||||
|  | GIT_EXEC_PATH=$(pwd)/.. | ||||||
|  | export GIT_EXEC_PATH | ||||||
|  |  | ||||||
| # Test repository | # Test repository | ||||||
| test=trash | test=trash | ||||||
|  |  | ||||||
							
								
								
									
										7
									
								
								tag.c
								
								
								
								
							
							
						
						
									
										7
									
								
								tag.c
								
								
								
								
							|  | @ -75,8 +75,11 @@ int parse_tag_buffer(struct tag *item, void *data, unsigned long size) | ||||||
| 	item->tag[taglen] = '\0'; | 	item->tag[taglen] = '\0'; | ||||||
|  |  | ||||||
| 	item->tagged = lookup_object_type(object, type); | 	item->tagged = lookup_object_type(object, type); | ||||||
| 	if (item->tagged) | 	if (item->tagged && track_object_refs) { | ||||||
| 		add_ref(&item->object, item->tagged); | 		struct object_refs *refs = alloc_object_refs(1); | ||||||
|  | 		refs->ref[0] = item->tagged; | ||||||
|  | 		set_object_refs(&item->object, refs); | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
							
								
								
									
										13
									
								
								tree.c
								
								
								
								
							
							
						
						
									
										13
									
								
								tree.c
								
								
								
								
							|  | @ -148,6 +148,7 @@ int parse_tree_buffer(struct tree *item, void *buffer, unsigned long size) | ||||||
| { | { | ||||||
| 	void *bufptr = buffer; | 	void *bufptr = buffer; | ||||||
| 	struct tree_entry_list **list_p; | 	struct tree_entry_list **list_p; | ||||||
|  | 	int n_refs = 0; | ||||||
|  |  | ||||||
| 	if (item->object.parsed) | 	if (item->object.parsed) | ||||||
| 		return 0; | 		return 0; | ||||||
|  | @ -184,11 +185,21 @@ int parse_tree_buffer(struct tree *item, void *buffer, unsigned long size) | ||||||
| 			obj = &entry->item.blob->object; | 			obj = &entry->item.blob->object; | ||||||
| 		} | 		} | ||||||
| 		if (obj) | 		if (obj) | ||||||
| 			add_ref(&item->object, obj); | 			n_refs++; | ||||||
| 		entry->parent = NULL; /* needs to be filled by the user */ | 		entry->parent = NULL; /* needs to be filled by the user */ | ||||||
| 		*list_p = entry; | 		*list_p = entry; | ||||||
| 		list_p = &entry->next; | 		list_p = &entry->next; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	if (track_object_refs) { | ||||||
|  | 		struct tree_entry_list *entry; | ||||||
|  | 		unsigned i = 0; | ||||||
|  | 		struct object_refs *refs = alloc_object_refs(n_refs); | ||||||
|  | 		for (entry = item->entries; entry; entry = entry->next) | ||||||
|  | 			refs->ref[i++] = entry->item.any; | ||||||
|  | 		set_object_refs(&item->object, refs); | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	 Junio C Hamano
						Junio C Hamano