Compare commits

...

294 Commits

Author SHA1 Message Date
93dcab2937 GIT 0.99.9k
This is not 1.0rc4 yet, but to push the recent fixes out.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-25 16:35:20 -08:00
2a1ddc58e4 git-sh-setup: move the repository check to a core program.
Any core commands that use setup_git_directory() now check if
given GIT_DIR is really a valid repository, so the same check in
git-sh-setup can use it without reimplementing it in shell.
This commit changes git-sh-setup to use git-var command for
that, although any other commands would do.

Note that we export GIT_DIR explicitly when calling git-var;
without it, the caller of this script would use GIT_DIR that we
return (which is to assume ./.git unless the caller has it
elsewhere) while git-var would go up to find a .git directory in
our parent directories, which would be checking a different
directory from what our callers will be using.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-25 15:55:50 -08:00
5e7bfe2567 setup_git_directory: make sure GIT_DIR is a valid repository.
setup_git_directory() always trusted what the user told where
GIT_DIR was, and assumed that is a valid .git/ directory.  This
commit changes it to at least do the same level validation as
is_toplevel_directory() does -- has refs/, has objects/ unless
GIT_OBJECT_DIRECTORY is set, and has valid HEAD symlink or
symref.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-25 15:43:41 -08:00
5d318ce6a9 git-var: make it work in subdirectory.
Use setup_git_directory() so that it can find its .git
directory.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-25 15:16:35 -08:00
ae2b0f1518 git-sh-setup: die if outside git repository.
Now all the users of this script detect its exit status and die,
complaining that it is outside git repository.  So move the code
that dies from all callers to git-sh-setup script.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-25 13:49:17 -08:00
e8cc80d039 parse-remote and ls-remote clean-up.
There is no reason to use git-sh-setup from git-ls-remote.
git-parse-remote can help the caller to use .git/remotes
shortcut if it is run inside a git repository, but can still be
useful outside a git repositoryas long as the caller does not
use any shortcut.  Use "git-rev-parse --git-dir" to figure out
where the GIT_DIR is, instead of using git-sh-setup.

This also makes "git-ls-remote origin" to work from inside a
subdirectory of a git managed repository as a side effect.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-25 13:49:17 -08:00
f678dd180a Prevent "git-commit -a path1 path2..."
When you want to create a partial commit, giving -a by mistake
would ignore the given path.  Prevent it.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-25 13:33:14 -08:00
3a2f2bb354 config.c: avoid shadowing global.
This is purely cosmetic, but avoid shadowing "FILE *config_file"
global in git_config_set_multivar() function.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-25 11:10:49 -08:00
874fbc3323 Fix a warning about unused value.
Fix a warning:
  git.c:276: warning: value computed is not used

Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-25 03:38:41 -08:00
2c52a42dd7 cvsimport: Don't let local settings hinder cvs user-migration.
Avoid this by passing "--norc" to cvsps.

Signed-off-by: Andreas Ericsson <ae@op5.se>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-25 03:38:18 -08:00
ee72aeaf00 Rename git-config-set to git-repo-config
... and adjust all references.

Signed-off-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-24 11:10:40 -08:00
a50b870aa1 diff-tree: teach single-commit diff-tree to honour grafts
We used to read the commit objects by hand and ignored the grafts.
Rewrite it using lookup_commit() API, to make it grafts-aware.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-23 22:25:55 -08:00
9c20a47067 Teach update-index to read from ls-tree.
git-update-index --index-info can almost be usable to read from ls-tree
output to update the index (and not the working tree file) to HEAD commit,
but not quite.  It was designed to read from git-apply --index-info
output, and does not want " blob " in ls-tree output.  Accept that as well.

This lets us update "git-checkout <ent> <path>" that used to filter the
extra " blob " string out.  Noted by Luben.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-23 22:25:55 -08:00
b7884981f8 git-revert: make --edit default.
Revert always should explain why, so make --edit the default,
unless stdin is not a terminal.  If you really don't want to say
anything, you can say "git-revert --no-edit $commit", or if you
are really sick, you could also say "git-revert $commit </dev/null".
But please don't.

You can also say "git-cherry-pick --edit $commit".  Not editting
the commit log message is the default for cherry-pick.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-23 17:19:37 -08:00
30c7bb249e Allow editing of a revert-message
I think all commit operations should allow editing of the message (ie we
should do this for merges too), but that's _particularly_ true of doing a
"git revert".

We should always explain why we needed to revert something.

This patch adds a "-e" or "--edit" flag to "git revert", although I
actually suspect it should be on by default (and we should have a
"--no-edit" flag to disable it, probably together with an automatic
disable if stdin isn't a terminal).

Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-23 16:52:52 -08:00
073dab137a Fix git-mv for moving directories with 1 file
This is fixed by putting the file into @changedfiles/@addedfiles,
and not the directory this file is in.

Additionally, this fixes the behavior for attempting to overwrite
a file with a directory, and gives a message for all cases where
overwriting is not possible (file->dir,dir->file,dir->dir).

Thanks for Alexander Litvinov for noting this problem.

Signed-off-by: Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-23 16:51:26 -08:00
fbf8ac212c git-merge: make recursive the default strategy
git-pull invoked merge with recursive as the default strategy
for some time now; match it in the git-merge itself.  Also avoid
listing more than one strategy on default because we have only
one strategy that can resolve an octopus and we are already
counting heads here.  This reduces the need to stash away local
modifications.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-23 16:23:11 -08:00
b99a394cd1 pack-redundant: type cleanups.
Binary representation of object names are unsigned char[20], not
signed.  Also verbose output had %lu format printing size_t
without (unsigned long) cast other places already had, so match
that.  Using format %zu was suggested but might not be supported
as widely.

Noted by Morten Welinder, fixed with input from H. Peter Anvin
and Hideaki Yoshifuji.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-23 16:10:11 -08:00
c61642185d Fixed git:// IPv4 address problem when compiled with -DNO_IPV6.
Failure to dereference a pointer caused incorrect initialization of
the IPv4 address when calling connect() when compiled with -DNO_IPV6.

With this patch and yesterday's patch for git-daemon, it should now be
possible to use the native git protocol for both the client and server
on Cygwin.

Signed-off-by: Paul Serice <paul@serice.net>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-22 12:38:27 -08:00
d1ab157759 arguments cleanup and some formatting
Signed-off-by: Alex Riesen <ariesen@harmanbecker.com>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-22 12:38:25 -08:00
2b6e34c1a3 remove unused variable
It is just assigned, nothing more.

Signed-off-by: Alex Riesen <ariesen@harmanbecker.com>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-22 12:38:23 -08:00
60435f68bb speedup allocation in pack-redundant.c
Reuse discarded nodes of llists

Signed-off-by: Alex Riesen <ariesen@harmanbecker.com>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-22 12:38:21 -08:00
bb931cf9d7 Make git-pack-redundant take a list of unimportant objs on stdin
This lets us do "git-fsck-objects --full --unreachable | cut -d ' ' -f3 |
git-pack-redundant --all", which will keep git-pack-redundant from keeping
packs just because they contain unreachable objects.

Also add some more --verbose output.

Signed-off-by: Lukas Sandström <lukass@etek.chalmers.se>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-22 12:38:16 -08:00
302ebfe521 Merge http://www.kernel.org/pub/scm/gitk/gitk 2005-11-22 01:55:15 -08:00
c7d77dab93 git-var: constness and globalness cleanup.
var.c::git_var read function did not have to return writable
strings; make it and the functions it points at return const char *
instead.

ident.c::get_ident() did not need to be global, so make it
static.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-21 23:44:35 -08:00
9ce392f482 Move diff.renamelimit out of default configuration.
Otherwise we would end up linking all the unneeded stuff into git-daemon
only to link with git_default_config.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-21 23:00:50 -08:00
07f9247722 max-count in terms of intersection
When a path designation is given, max-count counts the number
of commits therein (intersection), not globally.

This avoids the case where in case path has been inactive
for the last N commits, --max-count=N and path designation
at git-rev-list is given, would give no commits.

Signed-off-by: Luben Tuikov <ltuikov@yahoo.com>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-21 21:50:00 -08:00
c3df856842 GIT: Fix compilation error in connect.c
Fix compilation error for gcc-2.95.

Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-21 20:51:22 -08:00
d6ebd2590c Introduce $(ALL_PROGRAMS) for 'all:' and 'install:' to operate on.
Remove $(SIMPLE_PROGRAMS) from $(PROGRAMS) so buildrules don't have
to be overridden.

Put $(SCRIPTS) with the other target-macros so it doesn't get lonely.

Signed-off-by: Andreas Ericsson <ae@op5.se>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-21 16:37:58 -08:00
1b1480ff6a rename/copy score parsing updates.
Better variant, which handles stuff like "4.5%" and rejects
"192.168.0.1".  Additionally, make sure numbers are unsigned (I'm making
them unsigned long just for the hell of it), to make sure that
artificial wraparound scenarios don't cause harm.

	-hpa

[jc: with this, -M100 changes its meaning back to 10%.  People
wanting to say "pure renames only" should now say -M100% or
-M1.0; sounds a bit like an earthquake, but arguably things are
more consistent this way ;-)]

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-21 14:54:33 -08:00
f35230fb11 git-daemon not listening when compiled with -DNO_IPV6
git-daemon was not listening when compiled with -DNO_IPV6.
socksetup() was not returning socket count when compiled with -DNO_IPV6.

Signed-off-by: Paul Serice <paul@serice.net>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-21 14:36:43 -08:00
ef07618fdd git-repack: Properly abort in corrupt repository
In a corrupt repository, git-repack produces a pack that does not
contain needed objects without complaining, and the result of this
combined with -d flag can be very painful -- e.g. a lossage of one
tree object can lead to lossage of blobs reachable only through that
tree.

Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-21 14:08:49 -08:00
b17e659dd4 Allow hierarchical section names
A .git/config like follows becomes valid with this patch:

	[remote.junio]
		url = git://git.kernel.org/pub/scm/git/git.git
		pull = master:junio todo:todo +pu:pu

	[remote.ibook]
		url = ibook:git/
		pull = master:ibook
		push = master:quetzal

(This patch only does the ini file thing, git-fetch and friends still
ignore these values).

Signed-off-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-21 14:04:28 -08:00
3dd94e3b2e git-config-set: Properly terminate strings with '\0'
When a lowercase version of the key was generated, it was not
terminated. Strangely enough, it worked on Linux and macosx anyway.
Just cygwin barfed.

Signed-off-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-21 14:04:22 -08:00
e814bc4d15 git-proxy updates.
This builds on top of the git-proxy mechanism Paul Collins did,
and updates its configuration mechanism.

 * GIT_PROXY_COMMAND environment variable is used as the
   catch-all fallback, as in the original.  This has not
   changed.

 * Renames proxy configuration variables to core.gitproxy; this
   has become a multi-value variable per list discussion, most
   notably from suggestion by Linus.

	[core]
	;# matches www.kernel.org as well
	gitproxy = netcatter for kernel.org
	gitproxy = netscatter for sample.xz
	gitproxy = none for mydomain.xz
	gitproxy = netcatter-default

   The values are command names, followed by an optional " for "
   and domainname; the first tail-match of the domainname
   determines which proxy command is used.  An entry without "
   for " matches any domain and can be used as the default.

   The command name "none" is special -- it tells the mechanism
   not to use any proxy command and use the native git://
   connection.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-21 13:48:58 -08:00
f801477645 proxy-command support for git://
Here is an updated patch that first looks for GIT_PROXY_COMMAND
in the environment and then git.proxycommand in the repository's
configuration file.  I have left the calling convention the same
argv[1] is the host and argv[2] is the port.

I've taken the hostname parsing verbatim from git_tcp_connect(),
so it should now support an explicit port number and whatever
that business with the square brackets is.  (Should I move this
to a helper function?)

Regarding internal vs. external hosts, the proxy command can
simply run netcat locally to internal hosts, so perhaps that is
sufficient.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-21 13:48:58 -08:00
ce335fe04f daemon: further tweaks.
- Do validation only on canonicalized paths
 - Run upload-pack with "." as repository argument

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-21 13:47:00 -08:00
4dbd135279 git-daemon support for user-relative paths.
Dropped a fair amount of reundant code in favour of the library code
in path.c

Added option --strict-paths with documentation, with backwards
compatibility for whitelist entries with symlinks.

Everything that worked earlier still works insofar as I have
remembered testing it.

Signed-off-by: Andreas Ericsson <ae@op5.se>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-21 13:47:00 -08:00
aa7f412abf tutorial: setting up a tree for subsystem maintainers
The "copying over packs" step is to prevent the objects
available in upstream repository to get expanted in the
subsystem maintainer tree, and is still valid if the upstream
repository do not live on the same machine.  But if they are on
the same machine using objects/info/alternates is cleaner.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-21 13:42:55 -08:00
9f70b80692 rename detection with -M100 means "exact renames only".
When the user is interested in pure renames, there is no point
doing the similarity scores.  This changes the score argument
parsing to special case -M100 (otherwise, it is a precision
scaled value 0 <= v < 1 and would mean 0.1, not 1.0 --- if you
do mean 0.1, you can say -M1), and optimizes the diffcore_rename
transformation to only look at pure renames in that case.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-21 12:21:24 -08:00
88b5a74883 format-patch: fix two-argument special case, and make it easier to pick single commits
Luben Tuikov noticed that sometimes being able to say
'git-format-patch <commit>' to format the change a single commit
introduces relative to its parent is handy.

This patch does not support that directly, but it makes sense to
interpret a single argument "rev" to mean "rev^1..rev".

With this, the backward compatibility syntaxes still apply:

 - "format-patch master" means "format-patch master..HEAD"
 - "format-patch origin master" means "format-patch origin..master"
 - "format-patch origin.." means "format-patch origin..HEAD"

But "format-patch a b c d e" formats the changes these five
commits introduce relative to their respective parents.  Earlier
it rejected these arguments not in "one..two" form.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-21 12:21:24 -08:00
60abce3c0f Fix hooks/update template.
Make the example address RFC2606 (aka BCP0032) compliant.  Also
fix a couple of shell script errors.

Noted and fixed by Matthew Wilcox and Andreas Ericsson.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-21 12:21:06 -08:00
924215024c Make sure heads/foo and tags/foo do not confuse things.
When both heads/foo and tags/foo exist, get_sha1_basic("foo")
picked up the tag without complaining, which is quite confusing.
Make sure we require unambiguous form, "heads/foo" or "tags/foo"
in such cases.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-21 00:43:12 -08:00
e0a87193d3 Fix "do not DWIM" patch to enter_repo"
We wanted --strict to mean "do not DWIM", but the code required to
see absolute path.  daemon does its own path verification and chdirs
to the verified repository, so enter_repo() called from upload-pack
will always enter ".".  Requiring absolute path does not make any sense.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-20 23:37:13 -08:00
936a23420c git-reset.txt: Small fix + clarifications.
This basically translates the man-page from 'git-developerish' to plain
english, adding some almost-sample output from git-status so users can
recognize what will happen.

Also mention explicitly that --mixed updates the index, while --soft
doesn't. I understood the old text to mean "--mixed is exactly like
--soft, but verbose".

Signed-off-by: Andreas Ericsson <ae@op5.se>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-20 22:19:58 -08:00
3d32051f4f Add Python version checks to the Makefile to automatically set WITH_OWN_SUBPROCESS_PY
Also rearrange some path settings in the Makefile in the process.

Signed-off-by: Ryan Anderson <ryan@michonline.com>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-20 22:17:56 -08:00
bd22c904a0 Fix sparse warnings
Make some functions static and convert func() function prototypes to to
func(void).  Fix declaration after statement, missing declaration and
redundant declaration warnings.

Signed-off-by: Timo Hirvonen <tihirvon@gmail.com>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-20 22:14:16 -08:00
757f17bca5 gitk: Disable fastdate stuff for now
It has a fatal flaw in that it only handles timezones that are a
multiple of an hour.  It's really only needed with Tk8.5, where
the clock format command has been reimplemented in Tcl and is much
slower than in Tk8.4.

Signed-off-by: Paul Mackerras <paulus@samba.org>
2005-11-21 09:56:07 +11:00
8fc66df237 Merge http://www.kernel.org/pub/scm/gitk/gitk 2005-11-20 12:18:13 -08:00
f98d863d21 git-config-set: support selecting values by non-matching regex
Extend the regex syntax of value_regex so that prepending an exclamation
mark means non-match:

	[core]
		quetzal = "Dodo" for Brainf*ck
		quetzal = "T. Rex" for Malbolge
		quetzal = "cat"

You can match the third line with

	git-config-set --get quetzal '! for '

Signed-off-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-20 10:53:06 -08:00
a6322d079b merge-recursive: Replace 'except:'
Plain except:s are evil as they will catch all kinds of exceptions
including NameError and AttrubiteError.

Signed-off-by: Fredrik Kuivinen <freku045@student.liu.se>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-20 10:47:16 -08:00
9ae2172aed merge-one-file: use rmdir -p
The flag is universally available, even on VMS; use it.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-20 10:40:31 -08:00
f6e2869f48 gitk: Fix some bugs introduced by speedup changes
Commits that weren't read from git-rev-list, i.e. the ones displayed
with an open circle, were displayed incorrectly: the headline was
null if there was only one line, and the commit comment was put all
on one line.  Also, the terminal commits weren't displayed when -r
was used.

Signed-off-by: Paul Mackerras <paulus@samba.org>
2005-11-20 23:08:22 +11:00
13cfdfd5fa Documentation: add hooks/update example.
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-19 23:50:48 -08:00
4ddba79db7 git-config-set: add more options
... namely

--replace-all, to replace any amount of matching lines, not just 0 or 1,
--get, to get the value of one key,
--get-all, the multivar version of --get, and
--unset-all, which deletes all matching lines from .git/config

Signed-off-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-19 23:15:07 -08:00
7b5d895da6 Documentation update for user-relative paths.
Signed-off-by: Andreas Ericsson <ae@op5.se>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-19 20:50:39 -08:00
faea9ccbad Client side support for user-relative paths.
With this patch, the client side passes identical paths for these two:
	ssh://host.xz/~junio/repo
	host.xz:~junio/repo

Signed-off-by: Andreas Ericsson <ae@op5.se>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-19 20:50:39 -08:00
8d63013291 Server-side support for user-relative paths.
This patch basically just removes the redundant code from
{receive,upload}-pack.c in favour of the library code in path.c.

Signed-off-by: Andreas Ericsson <ae@op5.se>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-19 20:50:38 -08:00
0870ca7fab Do not DWIM in userpath library under strict mode.
This should force git-daemon administrator's job a bit harder
because the exact paths need to be given in the whitelist, but
at the same time makes the auditing easier.

This moves validate_symref() from refs.c to path.c, because we
need to link path.c with git-daemon for its "enter_repo()", but
we do not want to link the daemon with the rest of git libraries
and its requirements.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-19 20:50:38 -08:00
54f4b87454 Library code for user-relative paths, take three.
This patch provides the work-horse of the user-relative paths feature,
using Linus' idea of a blind chdir() and getcwd() which makes it
remarkably simple.

Signed-off-by: Andreas Ericsson <ae@op5.se>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-19 20:50:37 -08:00
942c1f53ae Add test case for git-config-set
... includes the mean tests I mentioned on the list.

Signed-off-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-19 20:47:30 -08:00
2d2465c015 Add documentation for git-config-set
Signed-off-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-19 20:47:30 -08:00
1b1e59c508 Add git-config-set, a simple helper for scripts to set config variables
This is meant for the end user, who cannot be expected to edit
.git/config by hand.

Example:

	git-config-set core.filemode true

will set filemode in the section [core] to true,

	git-config-set --unset core.filemode

will remove the entry (failing if it is not there), and

	git-config-set --unset diff.twohead ^recar

will remove the unique entry whose value matches the regex "^recar"
(failing if there is no unique such entry).

It is just a light wrapper around git_config_set() and
git_config_set_multivar().

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-19 20:47:29 -08:00
10bea152a3 Add functions git_config_set() and git_config_set_multivar()
The function git_config_set() does exactly what you think it does.
Given a key (in the form "core.filemode") and a value, it sets the
key to the value. Example:

	git_config_set("core.filemode", "true");

The function git_config_set_multivar() is meant for setting variables which
can have several values for the same key. Example:

	[diff]
		twohead = resolve
		twohead = recarsive

the typo in the second line can be replaced by

	git_config_set_multivar("diff.twohead", "recursive", "^recar");

The third argument of the function is a POSIX extended regex which has to
match the value. If there is no key/value pair with a matching value, a new
key/value pair is added.

These commands are also capable of unsetting (deleting) entries:

	git_config_set_multivar("diff.twohead", NULL, "sol");

will delete the entry

		twohead = resolve

Signed-off-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-19 20:47:29 -08:00
0890098780 Decide whether to build http-push in the Makefile
The decision about whether to build http-push or not belongs in the
Makefile.  This follows Junio's suggestion to determine whether curl
is new enough to support http-push.

Signed-off-by: Nick Hengeveld <nickh@reactrix.com>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-19 20:17:25 -08:00
11979b98ad http.c: reorder to avoid compilation failure.
Move the static function get_curl_handle() around to make sure
its definition and declarations are seen by the compiler before
its first use.  Also remove an unused variable.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-19 20:17:25 -08:00
7b89996749 http-push memory/fd cleanup
Clean up memory and file descriptor usage

Signed-off-by: Nick Hengeveld <nickh@reactrix.com>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-19 20:17:25 -08:00
acf59575ca Improve XML parsing in http-push
Improved XML parsing - replace specialized doc parser callbacks with generic
functions that track the parser context and use document-specific callbacks
to process that data.

Signed-off-by: Nick Hengeveld <nickh@reactrix.com>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-19 20:17:25 -08:00
5e3a769186 Improve pack list response handling
Better response handling for pack list requests - a 404 means we do have
the list but it happens to be empty.

Signed-off-by: Nick Hengeveld <nickh@reactrix.com>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-19 20:17:24 -08:00
e388ab74db Make http-fetch request types more clear
Rename object request functions and data to make it more clear which type
of request is being processed - this is a response to the introduction of
slot callbacks and the definition of different types of requests such as
alternates_request.

Signed-off-by: Nick Hengeveld <nickh@reactrix.com>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-19 20:17:24 -08:00
29508e1efb Isolate shared HTTP request functionality
Move shared HTTP request functionality out of http-fetch and http-push,
and replace the two fwrite_buffer/fwrite_buffer_dynamic functions with
one fwrite_buffer function that does dynamic buffering.  Use slot
callbacks to process responses to fetch object transfer requests and
push transfer requests, and put all of http-push into an #ifdef check
for curl multi support.

Signed-off-by: Nick Hengeveld <nickh@reactrix.com>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-19 20:17:24 -08:00
80e21a9ed8 merge-recursive::removeFile: remove empty directories
When the last file in a directory is removed as the result of a
merge, try to rmdir the now-empty directory.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-19 19:57:54 -08:00
397c76697f merge-one-file: remove empty directories
When the last file in a directory is removed as the result of a
merge, try to rmdir the now-empty directory.

[jc: We probably could use "rmdir -p", but for now we do that by
hand for portability.]

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-19 19:50:44 -08:00
22a06b3c47 Documentation: rebase-from-internal minor updates.
git-commit -v flag has been the default for quite some time, so
do not mention it.  Also a typofix.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-19 19:21:11 -08:00
6ed64058e1 git-repack: do not do complex redundancy check.
With "-a", redundant pack removal is trivial, and otherwise
redundant pack removal is pointless; do not call
git-redundant-pack from this script.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-19 12:13:53 -08:00
a4caa52140 git-count-objects: dc replacement
Johannes suggested this earlier but I did not take it so
seriously because this command is not that important.  But this
probably matters on Cygwin which does not seem to come with
precompiled dc.  It is a mystery for me that anything that
mimics UNIX does not offer a dc, though.

I did the detection for the lack of dc command a bit differently
from the verison Johannes did.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-19 02:54:07 -08:00
e3fe532ddc gitk: moving all three panes if clicking on an arrow.
Signed-off-by: Stefan-W. Hahn <stefan.hahn@s-hahn.de>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-19 00:24:40 -08:00
fd913b3910 gitk: use git-diff-tree --no-commit-id
gitk switched to use git-diff-tree with one argument in gettreediffs and
getblobdiffs.  git-diff-tree with one argument outputs commit ID in from
of the patch.  This causes an empty line after "Comments" in the lower
right pane.  Also, the diff in the lower left pane has the commit ID,
which is useless there.

This patch makes git use the newly added -no-commit-id option for
git-diff-tree to suppress commit ID.  It also removes the p variable in
both functions, since it has become useless after switching to the
one-argument invocation for git-diff-tree.

Signed-off-by: Pavel Roskin <proski@gnu.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-19 00:00:37 -08:00
e246483dc5 gitk: Specify line hover font
Hovering over a line in gitk displays the commit one-liner in a
box, but the text usually overflows the box.  The box size is
computed with a specified font, so this patch sets the text font
as well.

Signed-off-by: Frank Sorenson <frank@tuxrocks.com>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-18 23:55:50 -08:00
36a7cad6e4 readrefs: grab all refs with one call to ls-remote.
Instead of reading refs/heads/* and refs/tags/* files ourselves
and missing files in subdirectories of heads/ and tags/, use
ls-remote on local repository and grab all of them.  This lets us
also remove the procedure readotherrefs.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-18 23:54:17 -08:00
3eeb419968 Merge http://www.kernel.org/pub/scm/gitk/gitk 2005-11-18 17:43:38 -08:00
52b6536c62 Merge branch 'master' 2005-11-18 16:58:51 -08:00
0b4276931f Merge branches 'jc/branch' and 'jc/rebase' 2005-11-18 15:54:23 -08:00
7f59dbbb8f Rewrite rebase to use git-format-patch piped to git-am.
The current rebase implementation finds commits in our tree but
not in the upstream tree using git-cherry, and tries to apply
them using git-cherry-pick (i.e. always use 3-way) one by one.

Which is fine, but when some of the changes do not apply
cleanly, it punts, and punts badly.

Suppose you have commits A-B-C-D-E since you forked from the
upstream and submitted the changes for inclusion.  You fetch
from upstream head U and find that B has been picked up.  You
run git-rebase to update your branch, which tries to apply
changes contained in A-C-D-E, in this order, but replaying of C
fails, because the upstream got changes that touch the same area
from elsewhere.

Now what?

It notes that fact, and goes ahead to apply D and E, and at the
very end tells you to deal with C by hand.  Even if you somehow
managed to replay C on top of the result, you would now end up
with ...-B-...-U-A-D-E-C.

Breaking the order between B and others was the conscious
decision made by the upstream, so we would not worry about it,
and even if it were worrisome, it is too late for us to fix now.
What D and E do may well depend on having C applied before them,
which is a problem for us.

This rewrites rebase to use git-format-patch piped to git-am,
and when the patch does not apply, have git-am fall back on
3-way merge.  The updated diff/patch pair knows how to apply
trivial binary patches as long as the pre- and post-images are
locally available, so this should work on a repository with
binary files as well.

The primary benefit of this change is that it makes rebase
easier to use when some of the changes do not replay cleanly.
In the "unapplicable patch in the middle" case, this "rebase"
works like this:

 - A series of patches in e-mail form is created that records
   what A-C-D-E do, and is fed to git-am.  This is stored in
   .dotest/ directory, just like the case you tried to apply
   them from your mailbox.  Your branch is rewound to the tip of
   upstream U, and the original head is kept in .git/ORIG_HEAD,
   so you could "git reset --hard ORIG_HEAD" in case the end
   result is really messy.

 - Patch A applies cleanly.  This could either be a clean patch
   application on top of rewound head (i.e. same as upstream
   head), or git-am might have internally fell back on 3-way
   (i.e.  it would have done the same thing as git-cherry-pick).
   In either case, a rebased commit A is made on top of U.

 - Patch C does not apply.  git-am stops here, with conflicts to
   be resolved in the working tree.  Yet-to-be-applied D and E
   are still kept in .dotest/ directory at this point.  What the
   user does is exactly the same as fixing up unapplicable patch
   when running git-am:

   - Resolve conflict just like any merge conflicts.
   - "git am --resolved --3way" to continue applying the patches.

 - This applies the fixed-up patch so by definition it had
   better apply.  "git am" knows the patch after the fixed-up
   one is D and then E; it applies them, and you will get the
   changes from A-C-D-E commits on top of U, in this order.

I've been using this without noticing any problem, and as people
may know I do a lot of rebases.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-18 15:53:15 -08:00
eb777612f0 git-branch: -f to forcibly reset branch head.
A new usage, 'git-branch -f branch [start]', resets the branch head at
start (or current head).  Should be considered a dangerous operation,
but if you are like me to keep rewinding branches it is handy.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-18 15:53:12 -08:00
f9039f30d5 Do not show .exe in git command list.
Truncate the result from readdir() in the exec-path if they end
with .exe, to make it a bit more readable on Cygwin.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-18 15:40:22 -08:00
9a888b758f Document the "ignore objects" feature of git-pack-redundant
Signed-off-by: Lukas Sandström <lukass@etek.chalmers.se>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-18 15:34:19 -08:00
06a45c8cc9 Improve the readability of git-pack-redundant
Signed-off-by: Lukas Sandström <lukass@etek.chalmers.se>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-18 15:34:17 -08:00
62af0b532b Remove all old packfiles when doing "git repack -a -d"
No point in running git-pack-redundant if we already know
which packs are redundant.

Signed-off-by: Lukas Sandström <lukass@etek.chalmers.se>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-18 14:26:31 -08:00
4d16f8de16 Update pull/fetch --tags documentation
When fetching/pulling from a remote repository the "--tags" option
can be used to pull tags too.  Document that it will limit the pull
to only commits reachable from the tags.

Signed-off-by: Tony Luck <tony.luck@intel.com>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-18 14:25:10 -08:00
0cb022e052 Fix a bug in get_all_permutations.
This line was missing in the previous patch for some reason.

Signed-off-by: Lukas Sandström <lukass@etek.chalmers.se>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-18 14:25:06 -08:00
2e67a5f449 Cygwin *might* be helped with NO_MMAP
When HPA added Cygwin target, it ran just fine without NO_MMAP for him,
but recently we are getting reports that for some people things break
without it.  For now, just suggest it in the Makefile without actually
updating the default.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-18 11:22:27 -08:00
a8aca418d6 Teach "approxidate" about weekday syntax
On Fri, 18 Nov 2005, David Roundy wrote:
>
> Don't forget "high noon"!  (and perhaps "tea time"?)  :)

Done.

    [torvalds@g5 git]$ ./test-date "now" "midnight" "high noon" "tea-time"
    now -> bad -> Wed Dec 31 16:00:00 1969
    now -> Fri Nov 18 08:50:54 2005

    midnight -> bad -> Wed Dec 31 16:00:00 1969
    midnight -> Fri Nov 18 00:00:00 2005

    high noon -> bad -> Wed Dec 31 16:00:00 1969
    high noon -> Thu Nov 17 12:00:00 2005

    tea-time -> bad -> Wed Dec 31 16:00:00 1969
    tea-time -> Thu Nov 17 17:00:00 2005

Thanks for pointing out tea-time.

This is also written to easily extended to allow people to add their own
important dates like Christmas and their own birthdays.

Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-18 11:21:44 -08:00
583122cd1b Make "git fetch" less verbose by default
When doing something like

	git fetch --tags origin

the excessively verbose output of git fetch makes the result totally
unreadable. It's impossible to tell if it actually fetched anything new or
not, since the screen will fill up with an endless supply of

   ...
   * committish: 9165ec17fd
     tag 'v0.99.7c' of master.kernel.org:/pub/scm/git/git
   * refs/tags/v0.99.7c: same as tag 'v0.99.7c' of master.kernel.org:/pub/scm/git/git
   ...

and any new tags that got fetched will be totally hidden.

So add a new "--verbose" flag to "git fetch" to enable this verbose mode,
but make the default be quiet.

NOTE! The quiet mode will still report about new or changed heads, so if
you are really fetching a new head, you'll see something like this:

   [torvalds@g5 git]$ git fetch --tags parent
   Packing 6 objects
   Unpacking 6 objects
    100% (6/6) done
   * refs/tags/v1.0rc2: storing tag 'v1.0rc2' of master.kernel.org:/pub/scm/git/git
   * refs/tags/v1.0rc3: storing tag 'v1.0rc3' of master.kernel.org:/pub/scm/git/git
   * refs/tags/v1.0rc1: storing tag 'v1.0rc1' of master.kernel.org:/pub/scm/git/git

which actually tells you something useful that isn't hidden by all the
useless crud that you already had.

Extensively tested (hey, for me, this _is_ extensive) by doing a

   rm .git/refs/tags/v1.0rc*

and re-fetching with both --verbose and without.

NOTE! This means that if the fetch didn't actually fetch anything at all,
git fetch will be totally quiet. I think that's much better than being so
verbose that you can't even tell whether something was fetched or not, but
some people might prefer to get a "nothing to fetch" message in that case.

Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-18 11:21:22 -08:00
3afd169480 Fix bug introduced by the latest changes to git-pack-redundant
I forgot to initialize part of the pll struct when copying it.
Found by valgrind.

Signed-off-by: Lukas Sandström <lukass@etek.chalmers.se>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-18 11:20:34 -08:00
c3e24a7d46 git-prune: quote possibly empty $dryrun as parameter to test
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-18 11:16:09 -08:00
6eb668df76 Merge branch 'master' 2005-11-18 00:11:28 -08:00
087b6742fc git-am: --binary; document --resume and --binary.
Now git-apply can grok binary replacement patches, give --binary
flag to git-am.  As a safety measure, this is not by default
enabled, so that you do not let malicious e-mailed patch to
replace an arbitrary path with just a couple of lines (diff
index lines, the filename and string "Binary files "...) by
accident.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-17 22:36:31 -08:00
6b7b042772 Teach "approxidate" about weekday syntax
This allows people to use syntax like "last thursday" for the approxidate.

(Or, indeed, more complex "three thursdays ago", but I suspect that would
be pretty unusual).

NOTE! The parsing is strictly sequential, so if you do

	"one day before last thursday"

it will _not_ do what you think it does. It will take the current time,
subtract one day, and then go back to the thursday before that. So to get
what you want, you'd have to write it the other way around:

	"last thursday and one day before"

which is insane (it's usually the same as "last wednesday" _except_ if
today is Thursday, in which case "last wednesday" is yesterday, and "last
thursday and one day before" is eight days ago).

Similarly,

	"last thursday one month ago"

will first go back to last thursday, and then go back one month from
there, not the other way around.

I doubt anybody would ever use insane dates like that, but I thought I'd
point out that the approxidate parsing is not exactly "standard English".

Side note 2: if you want to avoid spaces (because of quoting issues), you
can use any non-alphanumberic character instead. So

	git log --since=2.days.ago

works without any quotes.

Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-17 22:34:50 -08:00
751a71e2b5 Make git-pack-redundant non-horribly slow on large sets of packs
Change the smallest-set detection algortithm so that when
we have found a good set, we don't check any larger sets.

Signed-off-by: Lukas Sandström <lukass@etek.chalmers.se>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-17 21:29:12 -08:00
0adb3358f6 git-repack: Fix variable name
Three times remove_redandant -> remove_redundant.

Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-17 21:28:45 -08:00
d2ac1cd263 'make clean' forgot about some files
Signed-off-by: Nicolas Pitre <nico@cam.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-17 21:28:39 -08:00
3200d1aee0 Deal with binary diff output from GNU diff 2.8.7
Some vintage of diff says just "Files X and Y differ\n", instead
of "Binary files X and Y differ\n", so catch both patterns.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-17 21:14:29 -08:00
a575603af2 Merge branch 'tojunio' of http://locke.catalyst.net.nz/git/git-martinlanghoff 2005-11-17 02:00:25 -08:00
fee3365fe1 archimport: allow for old style branch and public tag names
This patch adds the -o switch, which lets old trees tracked by
git-archmirror continue working with their old branch and tag names
to make life easier for people tracking your tree.

Private tags that are only used internally by git-archimport continue to be
new-style, and automatically converted upon first run.

[ ml: rebased to skip import overhaul ]

Signed-off-by:: Eric Wong <normalperson@yhbt.net>
Signed-off-by: Martin Langhoff <martin@catalyst.net.nz>
2005-11-17 21:20:45 +13:00
1e9eb2e937 Merge branch 'master' 2005-11-17 00:02:56 -08:00
f30c95dd76 Add approxidate test calls.
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-16 23:54:37 -08:00
3c07b1d194 git's rev-parse.c function show_datestring presumes gnu date
Ok. This is the insane patch to do this.

It really isn't very careful, and the reason I call it "approxidate()"
will become obvious when you look at the code. It is very liberal in what
it accepts, to the point where sometimes the results may not make a whole
lot of sense.

It accepts "last week" as a date string, by virtue of "last" parsing as
the number 1, and it totally ignoring superfluous fluff like "ago", so
"last week" ends up being exactly the same thing as "1 week ago". Fine so
far.

It has strange side effects: "last december" will actually parse as "Dec
1", which actually _does_ turn out right, because it will then notice that
it's not December yet, so it will decide that you must be talking about a
date last year. So it actually gets it right, but it's kind of for the
"wrong" reasons.

It also accepts the numbers 1..10 in string format ("one" .. "ten"), so
you can do "ten weeks ago" or "ten hours ago" and it will do the right
thing.

But it will do some really strange thigns too: the string "this will last
forever", will not recognize anyting but "last", which is recognized as
"1", which since it doesn't understand anything else it will think is the
day of the month. So if you do

	gitk --since="this will last forever"

the date will actually parse as the first day of the current month.

And it will parse the string "now" as "now", but only because it doesn't
understand it at all, and it makes everything relative to "now".

Similarly, it doesn't actually parse the "ago" or "from now", so "2 weeks
ago" is exactly the same as "2 weeks from now". It's the current date
minus 14 days.

But hey, it's probably better (and certainly faster) than depending on GNU
date. So now you can portably do things like

	gitk --since="two weeks and three days ago"
	git log --since="July 5"
	git-whatchanged --since="10 hours ago"
	git log --since="last october"

and it will actually do exactly what you thought it would do (I think). It
will count 17 days backwards, and it will do so even if you don't have GNU
date installed.

(I don't do "last monday" or similar yet, but I can extend it to that too
if people want).

It was kind of fun trying to write code that uses such totally relaxed
"understanding" of dates yet tries to get it right for the trivial cases.
The result should be mixed with a few strange preprocessor tricks, and be
submitted for the IOCCC ;)

Feel free to try it out, and see how many strange dates it gets right. Or
wrong.

And if you find some interesting (and valid - not "interesting" as in
"strange", but "interesting" as in "I'd be interested in actually doing
this) thing it gets wrong - usually by not understanding it and silently
just doing some strange things - please holler.

Now, as usual this certainly hasn't been getting a lot of testing. But my
code always works, no?

		Linus

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-16 23:54:37 -08:00
22ff00fc8b Disambiguate the term 'branch' in Arch vs git
Disambiguate the term 'branch' in Arch vs git,
and start using fully-qualified names.

Signed-off-by: Eric Wong <normalperson@yhbt.net>
Signed-off-by: Martin Langhoff <martin@catalyst.net.nz>
2005-11-17 20:29:36 +13:00
9b626e752e archimport: don't die on merge-base failure
Don't die if we can't find a merge base, Arch allows arbitrary
cherry-picks between unrelated branches and we should not
die when that happens

Signed-off-by: Eric Wong <normalperson@yhbt.net>
Signed-off-by: Martin Langhoff <martin@catalyst.net.nz>
2005-11-17 20:29:35 +13:00
a7fb51d3d4 remove shellquote usage for tags
use ',' to encode '/' in "archivename/foo--bar--0.0" so we can allow
"--branch"-less trees which are valid in Arch ("archivename/foo--0.0")

Signed-off-by: Eric Wong <normalperson@yhbt.net>
Signed-off-by: Martin Langhoff <martin@catalyst.net.nz>
2005-11-17 20:29:35 +13:00
27dedf0c3b GIT 0.99.9j aka 1.0rc3
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-16 21:32:44 -08:00
a8883288fa daemon.c: fix arg parsing bugs
Allow --init-timeout and --timeout to be specified without falling
through to usage().

Make sure openlog() is called even if implied by --inetd, or messages
will be sent to wherever LOG_USER ends up.

Signed-off-by: Andreas Ericsson <ae@op5.se>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-16 20:34:26 -08:00
fbba222f5d tests: binary diff application.
This adds more tests to cover cases where binary diff
application succeeds.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-16 16:20:41 -08:00
80b1e511d7 diff: --full-index
A new option, --full-index, is introduced to diff family.  This
causes the full object name of pre- and post-images to appear on
the index line of patch formatted output, to be used in
conjunction with --allow-binary-replacement option of git-apply.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-16 16:20:40 -08:00
011f4274bb apply: allow-binary-replacement.
A new option, --allow-binary-replacement, is introduced.

When you feed a diff that records full SHA1 name of pre- and
post-image blob on its index line to git-apply with this option,
the post-image blob replaces the path if what you have in the
working tree matches the pre-image _and_ post-image blob is
already available in the object directory.

Later we _might_ want to enhance the diff output to also include
the full binary data of the post-image, to make this more
useful, but this is good enough for local rebasing application.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-16 16:20:40 -08:00
0c15cc921a git-am: --resolved.
After failed patch application, you can manually apply the patch
(this includes resolving the conflicted merge after git-am falls
back to 3-way merge) and run git-update-index on necessary paths
to prepare the index file in a shape a successful patch
application should have produced.  Then re-running git-am --resolved
would record the resulting index file along with the commit log
information taken from the patch e-mail.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-16 16:19:11 -08:00
92927ed0aa git-apply: fail if a patch cannot be applied.
Recently we fixed 'git-apply --stat' not to barf on a binary
differences.  But it accidentally broke the error detection when
we actually attempt to apply them.

This commit fixes the problem and adds test cases.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-16 14:12:56 -08:00
5b4525eb8b git-cvsexportcommit.perl: fix typos in output
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-16 13:20:59 -08:00
8b3fbeef39 git-cvsexportcommit.perl: exit with non-0 status if patch fails.
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-16 13:20:59 -08:00
ebdbfa8b55 git-cvsexportcommit.perl: use getopts to get binary flags
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-16 13:20:58 -08:00
0ff2ce9d8a git-cvsexportcommit.perl: Fix usage() output.
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-16 13:20:58 -08:00
565cb99114 Documentation/git-log.txt: trivial typo fix.
Signed-off-by: Alecs King <alecsk@gmail.com>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-16 13:19:37 -08:00
8366a10ab2 symref support for import scripts
Fix git import script not to assume that .git/HEAD is a symlink.

Signed-off-by: Pavel Roskin <proski@gnu.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-16 13:19:18 -08:00
c0c35d5e41 Disallow empty pattern in "git grep"
For some reason I've done a "git grep" twice with no pattern, which is
really irritating, since it just grep everything. If I actually wanted
that, I could do "git grep ^" or something.

So add a "usage" message if the pattern is empty.

Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-16 13:17:46 -08:00
7dbc2c0402 git wrapper: basic fixes.
Updates to fix the nits found during the list discussion.

 - Lose PATH_TO_MAN; just rely on execlp() to find whereever the
   "man" command is installed.

 - Do not randomly chdir(), but concatenate to the current
   working directory only if the given path is not absolute.

 - Lose use of glob(); read from exec_path and do sorting
   ourselves -- it is not that much more work.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-15 23:13:30 -08:00
ad4f4daae8 Give python a chance to find "backported" modules
python 2.2.1 is perfectly capable of executing git-merge-recursive,
provided that it finds heapq and sets. All you have to do is to steal
heapq.py and sets.py from python 2.3 or newer, and drop them in your
GIT_PYTHON_PATH.

Signed-off-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-15 22:10:59 -08:00
a0fa2a10b4 Fix tests with new git in C
GIT_EXEC_PATH *has* to be set.

Signed-off-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-15 22:10:58 -08:00
1a41e743c6 Fix llist_sorted_difference_inplace in git-pack-redundant
Simplify and actually make llist_sorted_difference_inplace work
by using llist_sorted_remove instead of duplicating parts of the
code.

Signed-off-by: Lukas Sandström <lukass@etek.chalmers.se>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-15 21:19:56 -08:00
97fc6c5fba git --help COMMAND brings up the git-COMMAND man-page.
It's by design a bit stupid (matching ^git rather than ^git-), so as
to work with 'gitk' and 'git' as well.

Signed-off-by: Andreas Ericsson <ae@op5.se>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-15 16:03:00 -08:00
cb22bc4447 Update git(7) man-page for the C wrapper.
The program 'git' now has --exec-path which needs explaining.

Renamed old "DESCRIPTION" to "CORE GIT COMMANDS" to make room for
"OPTIONS" while following follow some sort of convention.

Also updated AUTHORS section to pat my own back a bit.

Signed-off-by: Andreas Ericsson <ae@op5.se>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-15 16:02:59 -08:00
8e49d50388 C implementation of the 'git' program, take two.
This patch provides a C implementation of the 'git' program and
introduces support for putting the git-* commands in a directory
of their own. It also saves some time on executing those commands
in a tight loop and it prints the currently available git commands
in a nicely formatted list.

The location of the GIT_EXEC_PATH (name discussion's closed, thank gods)
can be obtained by running

	git --exec-path

which will hopefully give porcelainistas ample time to adapt their
heavy-duty loops to call the core programs directly and thus save
the extra fork() / execve() overhead, although that's not really
necessary any more.

The --exec-path value is prepended to $PATH, so the git-* programs
should Just Work without ever requiring any changes to how they call
other programs in the suite.

Some timing values for 10000 invocations of git-var >&/dev/null:
	git.sh: 24.194s
	git.c:   9.044s
	git-var: 7.377s

The git-<tab><tab> behaviour can, along with the someday-to-be-deprecated
git-<command> form of invocation, be indefinitely retained by adding
the following line to one's .bash_profile or equivalent:

	PATH=$PATH:$(git --exec-path)

Experimental libraries can be used by either setting the environment variable
GIT_EXEC_PATH, or by using

	git --exec-path=/some/experimental/exec-path

Relative paths are properly grok'ed as exec-path values.

Signed-off-by: Andreas Ericsson <ae@op5.se>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-15 16:02:57 -08:00
c0bbbb1ba9 sha1_file.c::add_packed_git(): fix type mismatch.
An object name is 20-byte 'unsigned char', not 'char'.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-15 15:08:28 -08:00
3299c6f6a8 diff: make default rename detection limit configurable.
A while ago, a rename-detection limit logic was implemented as a
response to this thread:

	http://marc.theaimsgroup.com/?l=git&m=112413080630175

where gitweb was found to be using a lot of time and memory to
detect renames on huge commits.  git-diff family takes -l<num>
flag, and if the number of paths that are rename destination
candidates (i.e. new paths with -M, or modified paths with -C)
are larger than that number, skips rename/copy detection even
when -M or -C is specified on the command line.

This commit makes the rename detection limit easier to use.  You
can have:

	[diff]
		renamelimit = 30

in your .git/config file to specify the default rename detection
limit.  You can override this from the command line; giving 0
means 'unlimited':

	git diff -M -l0

We might want to change the default behaviour, when you do not
have the configuration, to limit it to say 20 paths or so.  This
would also help the diffstat generation after a big 'git pull'.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-15 15:08:27 -08:00
f8348be3be Add config variable core.symrefsonly
This allows you to force git to avoid symlinks for refs. Just add
something like

	[core]
		symrefsonly = true

to .git/config.

Don´t forget to "git checkout your_branch", or it does not do anything...

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-15 11:42:29 -08:00
4a4e6fd74f Rework object refs tracking to reduce memory usage
Store pointers to referenced objects in a variable sized array instead
of linked list.  This cuts down memory usage of utilities which use
object references; e.g., git-fsck-objects --full on the git.git
repository consumes about 2 MB of memory tracked by Massif instead of
7 MB before the change.  Object refs are still the biggest consumer of
memory (57%), but the malloc overhead for a single block instead of a
linked list is substantially smaller.

Signed-off-by: Sergey Vlasov <vsu@altlinux.ru>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-15 11:42:29 -08:00
545f229a4b git-fsck-objects: Free tree entries after use
The Massif tool of Valgrind revealed that parsed tree entries occupy
more than 60% of memory allocated by git-fsck-objects.  These entries
can be freed immediately after use, which significantly decreases
memory consumption.

Signed-off-by: Sergey Vlasov <vsu@altlinux.ru>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-15 11:42:28 -08:00
a52e4ef877 Fix git(1) link to git-index-pack
Signed-off-by: Jonas Fonseca <fonseca@diku.dk>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-15 11:42:28 -08:00
cd0a781c38 Documentation: do not blindly run 'cat' .git/HEAD, or echo into it.
Many places in the documentation we still talked about reading
what commit is recorded in .git/HEAD or writing the new head
information into it, both assuming .git/HEAD is a symlink.  That
is not necessarily so.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-15 01:31:04 -08:00
313c4714c5 Fix bunch of fd leaks in http-fetch
The current http-fetch is rather careless about fd leakage, causing
problems while fetching large repositories. This patch does not reserve
exhaustiveness, but I covered everything I spotted. I also left some
safeguards in place in case I missed something, so that we get to know,
sooner or later.

Reported by Becky Bruce <becky.bruce@freescale.com>.

Signed-off-by: Petr Baudis <pasky@suse.cz>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-15 00:34:50 -08:00
bce8230d5d git-daemon: --inetd implies --syslog
Otherwise nothing is logged anywhere, which is a Bad Thing.

Signed-off-by: Andreas Ericsson <ae@op5.se>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-15 00:19:32 -08:00
8b649e27dd git-core-foo -> git-foo, except the core package
This patch renames the tarball "git" rather than "git-core", and changes
the names of various packages from git-core-foo to git-foo.  git-core is
still the true core package; an empty RPM package named "git" pulls in
ALL the git packages -- this makes updates work correctly, and allows
"yum install git" to do the obvious thing.

It also renames the git-(core-)tk package to gitk.

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-15 00:07:46 -08:00
60d64db461 GIT 0.99.9i aka 1.0rc2
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-14 18:39:18 -08:00
d7bba81575 Update topo-order test.
The recently we updated rev-list --topo-order to show the heads
in date order, but we had a test that expected to see the old
behaviour.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-14 18:15:30 -08:00
08db81a9f1 allow git-update-ref create refs with slashes in names
Make git-update-ref create references with slashes in them. git-branch
and git-checkout already support such reference names.

git-branch can use git-update-ref to create the references in a more
formal manner now.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-14 17:15:32 -08:00
7acab8f167 Documentation nitpicking
This patch fixes some small problems with the documentation.

Signed-off-by: Nikolai Weibull <nikolai@bitwi.se>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-14 17:15:32 -08:00
2db0bfbc04 Document a couple of missing command-line options.
This patch adds documentation to quite a few command-line options.

Signed-off-by: Nikolai Weibull <nikolai@bitwi.se>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-14 17:15:32 -08:00
b2309b7019 Document the -n command-line option to git-unpack-objects
This patch documents the -n command-line option to git-unpack-objects,
as it was previously undocumented.

Signed-off-by: Nikolai Weibull <nikolai@bitwi.se>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-14 17:15:32 -08:00
9add69b1b1 apply: fix binary patch detection.
The comparison to find "Binary files " string was looking at a
wrong place when offset != 0.

Also, we may have the full 40-byte textual sha1 on the index
line; two off-by-one errors prevented it.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-14 17:15:07 -08:00
232475d382 Add -r flag and some speedups
The -r flag means "rev-list order", i.e. just display the commits
in the order they come from git-rev-list.

The speedups include:
- don't process the whole commit line-by-line, only the header
- don't convert dates when reading the commits, rather do it when
  needed
- don't do the $canv delete lines.$id in drawlines when drawing the
  graph initially (it was taking a lot of the total time)
- cache the date conversion for each hour (more important with tk8.5,
  since [clock format] is a lot slower in 8.5 than in 8.4).

Signed-off-by: Paul Mackerras <paulus@samba.org>
2005-11-15 10:34:03 +11:00
2ed02887bd Fix git-rev-list "date order" with --topo-order
This fixes git-rev-list so that when there are multiple branches, we still
sort the heads in proper approximate date order even when sorting the
output topologically.

This makes things like

	gitk --all -d

work sanely and show the branches in date order (where "date order" is
obviously modified by the paren-child dependency requirements of the
topological sort).

The trivial fix is to just build the "work" list in date order rather than
inserting the new work entries at the beginning.

Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-14 14:16:38 -08:00
d4072c9722 git-branch: Mention -d and -D in man-page.
Signed-off-by: Andreas Ericsson <ae@op5.se>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-14 14:16:37 -08:00
b6ebac9e43 Merge branch 'svnup' of http://netz.smurf.noris.de/git/git
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-14 13:50:05 -08:00
0f3f5e3f69 Depend on asciidoc 7 (at least). 2005-11-14 17:41:31 +01:00
1331df8781 Remove git-rename. git-mv does the same
Signed-off-by: Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-14 00:50:18 -08:00
b0c698a6e4 Bugfix: stop if directory already exists
Fix a typo: We do not want to run the directory as command,
and want to terminate if the directory exists
Additionally, update the usage message

Signed-off-by: Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-14 00:50:17 -08:00
94d2331770 Separate LDFLAGS and CFLAGS.
Stuffing -L flag and friends meant for the linking phase into
ALL_CFLAGS is not right; honor LDFLAGS and introduce ALL_LDFLAGS
to separate them out.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-14 00:26:49 -08:00
6d5410d651 Merge branch 'svnup' of http://netz.smurf.noris.de/git/git 2005-11-14 00:25:48 -08:00
4b1ca25e42 Remove trailing slashes
SVN dies a messy death when passed a path with trailing slashes.
2005-11-14 08:31:00 +01:00
0086e2c854 Rename lost+found to lost-found.
Because we use "lost-found" as the directory name to hold
dangling object names, it is confusing to call the command
git-lost+found, although it makes sense and is even cute ;-).

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-13 02:07:02 -08:00
abacbe4166 Fix compilation warnings in pack-redundant.c
This fixes compilation warnings where "%ld" was used to print values of
type size_t.

Signed-off-by: Kai Ruemmler <kai.ruemmler@gmx.net>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-13 02:00:36 -08:00
ac0b86dadf Debian: build-depend on libexpat-dev.
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-13 01:57:33 -08:00
ba1dbb61ea Split gitk into seperate RPM package
I don't want to have to install x11-libs and all it's dependencies on
my headless machines, so this patch splits gitk out of the RPM.

The .deb already appears to have gitk split out.

Signed-off-by: Thomas Matysik <thomas@matysik.co.nz>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-13 01:33:26 -08:00
8614e92323 Add expat and expat-devel dependencies (for http-push) to RPM spec.
Signed-off-by: Thomas Matysik <thomas@matysik.co.nz>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-13 01:32:21 -08:00
54a9ba0d44 Fix fd leak in http-fetch
Added a call to finish_request to clean up resources if the server
returned a 404 and there are no alternates left to try.

Signed-off-by: Nick Hengeveld <nickh@reactrix.com>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-12 23:43:11 -08:00
acc075a8ad Fix for multiple alternates requests in http-fetch
Stop additional alternates requests from starting if one is already in
progress.  This adds an optional callback which is processed after a slot
has finished running.

Signed-off-by: Nick Hengeveld <nickh@reactrix.com>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-12 23:43:11 -08:00
ceae78b438 debian packaging: git-cvs needs cvsps 2005-11-12 23:15:50 +01:00
f7a2eb7359 GIT 0.99.9h
This is GIT 1.0-rc1 in disguise.  It is plausible that
relatively new parts of the system still need tweaking and
fixing, but that is why it is not 1.0 but rc ;-).

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-11 22:37:38 -08:00
7765e7ebda Ignore built git-lost+found.
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-11 22:28:03 -08:00
e6bd23911e Documentation: asciidoc sources are utf-8
git-pack-redundant documentation was encoded in latin1, which caused
asciidoc to barf, which expected to see utf-8.  Run tcs to re-encode
it in utf-8.

Also just for fun try my name in Japanese in git-lost+found
documentation ;-)

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-11 22:16:59 -08:00
07203659d0 Rename .git/lost+found to .git/lost-found.
Just to avoid confusion that scripts poorly written by somebody
else ;-) might mistake this as a mount point, or backup tools
ignoring the directory.  The latter is probably not a big loss,
however, considering that this directory's contents are to be
used while fresh anyway.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-11 21:52:21 -08:00
04e7ca1a1b git-lost+found
This command helps you resurrect accidentally lost tags and commits.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-11 21:52:20 -08:00
d7b1a1ddbe git-prune: prune redundant packs
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-11 21:19:11 -08:00
1c3039e8f1 Make git-pack-redundant consider alt-odbs
This patch changes git-pack-redundant so that packfiles
in alternate object directories also are considered when
deciding which objects are redundant.

This functionality is controlled by the flag '--alt-odb'.

Also convert the other flags to the long form, and update
docs and git-repack accordingly.

Signed-off-by: Lukas Sandström <lukass@etek.chalmers.se>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-11 21:19:11 -08:00
9bc0f32c77 Rename git-pack-intersect to git-pack-redundant
This patch renames git-pack-intersect to git-pack-redundant
as suggested by Petr Baudis. The new name reflects what the
program does, rather than how it does it.

Also fix a small argument parsing bug.

Signed-off-by: Lukas Sandström <lukass@etek.chalmers.se>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-11 21:19:11 -08:00
b4ad3552de Make git-repack use git-pack-intersect.
Signed-off-by: Lukas Sandström <lukass@etek.chalmers.se>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-11 21:19:11 -08:00
5231148202 Add git-pack-intersect to .gitignore
Signed-off-by: Lukas Sandström <lukass@etek.chalmers.se>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-11 21:19:10 -08:00
2a444781b1 Add documentation for git-pack-intersect
Signed-off-by: Lukas Sandström <lukass@etek.chalmers.se>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-11 21:19:10 -08:00
c283ab21c1 Add git-pack-intersect
This patch adds the program git-pack-intersect. It is
used to find redundant packs in git repositories.

Signed-off-by: Lukas Sandström <lukass@etek.chalmers.se>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-11 21:19:10 -08:00
fd66dbf529 merge-one-file: use empty- or common-base condintionally in two-stage merge.
If two sides added the same path completely different thing, it is
easier to see the merge pivoting on /dev/null.  So check the size of
the common section we have found, and empty it if it is too small.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-11 21:18:18 -08:00
e433705dd4 Documentation: git-apply --no-add
This is a specialized hack to help no-base merges, but other
people might find it useful, so let's document it.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-11 21:18:18 -08:00
cb93c19365 merge-one-file: use common as base, instead of emptiness.
Unlike the previous round that merged the path added differently
in each branches using emptiness as the base, compute a common
version and use it as input to 'merge' program.

This would show the resulting (still conflicting) file left in
the working tree as:

	common file contents...
	<<<<<< FILENAME
	version from our branch...
	======
	version from their branch...
	>>>>>> .merge_file_XXXXXX
	more common file contents...

when both sides added similar contents.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-11 21:18:17 -08:00
f7d24bbefb merge with /dev/null as base, instead of punting O==empty case
Instead of leaving the path unmerged in a case where each side
adds different version of the same path, attempt to merge it
with empty base and leave "our" version in the index file, just
like we do for the case in conflicting merge.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-11 21:18:17 -08:00
6fd72e39af Show URL in the "Getting <foo> list" http-fetch messages
Signed-off-by: Petr Baudis <pasky@suse.cz>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-11 21:14:46 -08:00
e9af60c88b merge-recursive: Use '~' instead of '_' to separate file names from branch names
Makes it less probable that we get a clash with an existing file,
furthermore Cogito already uses '~' for this purpose.

Signed-off-by: Fredrik Kuivinen <freku045@student.liu.se>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-11 21:14:39 -08:00
857f26d2f4 merge-recursive: Add copyright notice
Signed-off-by: Fredrik Kuivinen <freku045@student.liu.se>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-11 21:14:36 -08:00
46e651743a merge-recursive: Indent the output properly
If we have multiple common ancestors and have to recursively merge
them then the output will be much more readable with this commit.

Signed-off-by: Fredrik Kuivinen <freku045@student.liu.se>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-11 21:14:34 -08:00
5f3aa197ac Change 'cache' to 'index' in the docs
This patch makes the documentation refer to the index
as index instead of cache, but some references still
remain. (e.g. git-update-index.txt)

Signed-off-by: Lukas Sandström <lukass@etek.chalmers.se>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-11 15:12:29 -08:00
3cab3594e9 INSTALL: duplicate python requirements from Makefile
... and refer the reader to Makefile for other things that can be
tweaked.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-11 11:27:03 -08:00
631ba30907 Merge branches 'jc/sb' and 'jc/mb' 2005-11-11 10:52:59 -08:00
4bc51db0fe t1200: use --topo-order to keep the show-branch output stable.
Because a batch-oriented script creates many commits within a second
on a fast machine, show-branch output of the test results are unstable
without topo-order.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-11 10:52:39 -08:00
6b209d4733 Fully detect uninteresting commits.
With the change in the previous round, we are guaranteed to come up
with the list of all relevant merge bases, but sometimes we do not
fully mark unintersting ones due to a horizon effect.  Add a phase to
postprocess, so that we mark all ancestor of "interesting" commit.

This also changes the default ordering of shown commits back to
chronological order, and adds --topo-order flag to show them in
topological order.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-11 10:52:38 -08:00
9ce7028531 git-show-branch: tighten merge-base computation.
This makes the merge-base computation resistant to the pathological
case discussed on the list earlier, by doing the same logic as
git-merge-base.  As a side effect, it breaks the command's primary
function to list non-merge commit sequences, which needs to be fixed
separately.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-11 10:52:38 -08:00
53de71f88b Add test case for merge-base.
Although it was shown that the "full contamination" was not really full
during the list discussion, the series improves things without incurring
extra parsing cost, and here is a test to check that.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-11 10:52:31 -08:00
9e5f4a5539 merge-base: avoid unnecessary postprocessing.
When we have only one merge-base candidates in the result list,
there is no point going back to mark the reachable commits
again.  And that is the most common case, so try not to waste
time on it.  Suggested by Linus.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-11 10:52:31 -08:00
ed9a540b2b merge-base: fully contaminate the well.
The discussion on the list demonstrated a pathological case where
an ancestor of a merge-base can be left interesting.  This commit
introduces a postprocessing phase to fix it.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-11 10:52:30 -08:00
592ee97d8f RPM: arch submodule needs tla.
Noticed by Horst von Brand.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-11 09:33:47 -08:00
7f10f7c4e4 git-clone: Allow cloning into directories other than child of current dir.
This patch adds -p to mkdir and an explicit check to see if the target
directory exists (since mkdir -p doesn't throw an error if it does).

Signed-off-by: Andreas Ericsson <ae@op5.se>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-11 01:34:27 -08:00
0879aa2870 git-clone: Keep remote names when cloning unless explicitly told not to.
With this patch the following commands all clone into the local directory
"repo". If repo exists, it will still barf.

	git-clone git://host.xz/repo.git
	git-clone /path/to/repo/.git
	git-clone host.xz:repo.git

I ended up doing the same source-to-target sed'ing for all our company
projects, so it was easier to add it directly to git-clone.

Signed-off-by: Andreas Ericsson <ae@op5.se>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-11 01:34:26 -08:00
0867b0125a specfile cleanups
Some specfile cleanups after the split.
- zlib dependency fix, current method is inconsistent, you can
  potentially build a package that you can't install on machine you
  built it on
- Add proper defattr
- Remove trailing '.' in summary
- Add docs to split up packages
- Add git-core dependency for each subpackage
- Move arch import to separate package as well

Signed-off-by: Chris Wright <chrisw@osdl.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-11 01:24:31 -08:00
f84f9d38eb archimport: handle pika escaping
Arch uses pika escaping in some places (but not all!). Specifically, commits of
the type 'patch' use pika escaping in the log entries, which we parse to know
what to add/delete and what to commit.

This patch checks for hints of pika escaping and asks tla to unescape for us.

Originally implemented by Penny Leach <penny@catalyst.net.nz>

Signed-off-by: Martin Langhoff <martin@catalyst.net.nz>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-11 01:15:26 -08:00
0e9ab02da7 git-clone: quote destination directory name
git-clone doesn't quote the full path to the destination directory,
which causes it to fail if the path contains spaces or other characters
interpreted by the shell.

[jc: obviously I was not careful enough.  Pavel, thanks for catching.]

Signed-off-by: Pavel Roskin <proski@gnu.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-11 01:15:00 -08:00
601c978c1b Add --no-commit-id option for git-diff-tree, use it in gitk
This patch introduces -no-commit-id option for git-diff-tree, which
suppresses commit ID output.

[jc: dropped gitk part for now.]

Signed-off-by: Pavel Roskin <proski@gnu.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-11 01:13:05 -08:00
17cf939724 octopus: do not do AND'ed merge base.
When doing an octopus, we incorrectly used the previous merge
base as the reference to compute next merge base.  This was
unnecessary, because that can never be better than using the
original HEAD.  And that is far simpler as well ;-).

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-11 00:50:24 -08:00
ff56fe1ca7 Add --pretty=fuller
git log without --pretty showed author and author-date, while
with --pretty=full showed author and committer but no dates.
The new formatting option, --pretty=fuller, shows both name and
timestamp for author and committer.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-11 00:42:52 -08:00
e3e291fc07 Do not lose author name information to locale gotchas.
I noticed format-patch loses authorship information of Lukas' patch
when I run git tools with LC_LANG set to ja_JP.  It turns out that
the sed script to set environment variables were not working on his
name (encoded in UTF-8), which is unfortunate but technically correct.

Force sed invocation under C locale because we always want literal byte
semantics.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-11 00:37:34 -08:00
605607cc62 Documentation: "host:path/to/repo" is git native over ssh.
You could also spell it ssh://host:/path/to/repo (or git+ssh,
ssh+git), but without method:// is shorter to type, so mention
only that one in the short and sweet list.

Noticed by Pasky.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-11 00:37:34 -08:00
66c9ec2555 Let git-clone/git-fetch follow HTTP redirections
Otherwise, git-clone silently failed to clone a remote
repository where redirections (ie. a response with a
"Location" header line) are used.

This includes the fixes from Nick Hengeveld.

Signed-off-by: Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-10 15:57:56 -08:00
ad7db62113 Fix confusing git-update-ref error message
When git-update-ref has hit the "Ref %s changed to %s" error, I just stare
at it, left puzzled. This patch attempts to reword that to a more useful
and less confusing error message.

Signed-off-by: Petr Baudis <pasky@suse.cz>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-10 15:57:21 -08:00
14df4c4188 Add missing git-core and cvsps RPM dependencies.
Signed-off-by: Jim Radford <radford@blackbean.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-10 15:57:09 -08:00
23ea3e201c GIT 0.99.9g
Another snapshot, as slow and steady marth towards 1.0 continues.
Major changes include:

 - Jim Radford's RPM split.
 - Fredrik's recursive merge strategy is now default for two heads merge.
 - Yaacov's SVN importer updates.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-09 21:09:43 -08:00
a1c292958f Make git-recursive the default strategy for git-pull.
This does two things:

 - It changes the hardcoded default merge strategy for two-head
   git-pull from resolve to recursive.

 - .git/config file acquires two configuration items.
   pull.twohead names the strategy for two-head case, and
   pull.octopus names the strategy for octopus merge.

IOW you are paranoid, you can have the following lines in your
.git/config file and keep using git-merge-resolve when pulling
one remote:

	[pull]
		twohead = resolve

OTOH, you can say this:

	[pull]
		twohead = resolve
		twohead = recursive

to try quicker resolve first, and when it fails, fall back to
recursive.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-09 18:56:29 -08:00
13956670a7 Use 'merge-base --all' where applicable.
It may get extra merge base on truly pathological commit histories,
but is a lot easier to understand, explain, and prove correctness.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-09 18:54:14 -08:00
a489352e3d Merge branch 'hold/svn' 2005-11-09 18:44:42 -08:00
68afd5fab7 Merge branch 'hold/rpm' 2005-11-09 18:44:18 -08:00
ff36de0847 git-apply: do not fail on binary diff when not applying nor checking.
We run git-apply with --stat and --summary at the end of the pull
by default, which causes it to barf when the pull brought in changes
to binary files.  Just mark them as binary patch and proceed when
not applying nor checking.

[jc: I almost missed --check until I saw Linus did something similar.]

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-09 15:19:50 -08:00
c44922a781 Update INSTALL
Explicitly mention how to install by hand in build-as-user and
install-as-root steps.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-09 12:40:03 -08:00
186f855fc6 merge-recursive: Fix support for branch names containing slashes
A branch name could have a slash in it.

Signed-off-by: Fredrik Kuivinen <freku045@student.liu.se>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-09 12:32:36 -08:00
c8a4f5e542 merge-recursive: Fix limited output of rename messages
The previous code did the right thing, but it did it by accident.

Signed-off-by: Fredrik Kuivinen <freku045@student.liu.se>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-09 12:32:34 -08:00
e09f5d7b07 Fix cvsexportcommit syntax error
There is a syntax error in cvsexport script:

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-08 23:34:29 -08:00
f37d0cc3ff Update howto using-topic-branches
"git resolve" is being deprecated in favour of "git merge".
Update the documentation to reflect this.

Signed-off-by: Tony Luck <tony.luck@intel.com>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-08 21:33:36 -08:00
f4f440a039 sparse fixes for http-{fetch,push}.c
Make a bunch of needlessly global functions static, and replace two
K&R-style declarations.

Signed-off-by: Peter Hagervall <hager@cs.umu.se>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-08 21:33:32 -08:00
61f81518a2 git-tag -d <tag>: delete tag <tag>
This adds option '-d' to git-tag.sh and documents it.

Signed-off-by: Kai Ruemmler <kai.ruemmler@gmx.net>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-08 11:26:10 -08:00
23fc63bf8f make tests ignorable with "make -i"
Allow failed tests to be ignored using make's "-i". The patch also
disables parallel make in t/. This doesn't make the testing any
different as before: the tests were run sequentially before.

It also allows to run more tests, ignoring the ones usually failing
just to figure out if something else broke.  (Or to ignore plainly
uninteresting situations because of the testing being done on say...
cygwin ;)

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-08 11:26:07 -08:00
cb34882bd6 fix t5000-tar-tree.sh when $TAR isn't set
$TAR isn't set everywhere. Provide a default (tar)

Signed-off-by: Alex Riesen <raa.lkml@gmail.com>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-08 11:26:03 -08:00
f8d294f0a4 Clean build annoyance.
As Pasky pointed out, building in templates directory showed
list of built template files which was unneeded.  This commit
also fixes another build annoyance I recently left in by
accident.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-08 08:58:52 -08:00
5ca15b8af7 GIT 0.99.9f
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-08 01:25:59 -08:00
7d4de59b17 Separate RPMS for programs with non-standard dependencies.
Signed-off-by: Jim Radford <radford@blackbean.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-08 01:24:54 -08:00
f3ad062560 Fix a couple of obvious and insignificant typo.
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-08 01:24:50 -08:00
01d4f0e775 Lift the default limit of number of revs.
Now that the leak is gone, there is by default no limit of revisions to
import.  No more message about leak when the limit (given by the -l
parameter) is reached.

Signed-off-by: Yaacov Akiba Slama <ya@slamail.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-08 01:24:50 -08:00
a16db4f472 Handle a revision that only creates a new tag correctly.
Fix an error when a svn revision consists only of the creation of a new tag
directory (/tags/this_is_a_tag).

Signed-off-by: Yaacov Akiba Slama <ya@slamail.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-08 01:24:49 -08:00
109fc2b97b Bundle file copies from multiple branches into a merge.
When copying files and/or directories from several branches in one single
revision, all these branches are used as parents of the commit.

Signed-off-by: Yaacov Akiba Slama <ya@slamail.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-08 01:24:49 -08:00
8168373fe7 copy_dir becomes copy_path and handles both files and directories
The A (Add) and R (Replace) actions handling are unified.

Signed-off-by: Yaacov Akiba Slama <ya@slamail.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-08 01:24:48 -08:00
c2c07a5c2a Don't output error on changes in the nodes /, /tags or /branches
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-08 01:24:48 -08:00
cbce5d8961 Add node_kind function to differentiate between file and directory
Signed-off-by: Yaacov Akiba Slama <ya@slamail.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-08 01:24:48 -08:00
fcfa32b9e1 Use svn pools to solve the memory leak problem.
Signed-off-by: Yaacov Akiba Slama <ya@slamail.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-08 01:24:47 -08:00
4bfb6b62ff git-am: do not lose already edited final-commit when resuming.
The last round stopped munging the patch when resuming, but
failed to preserve final-commit.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-08 01:23:53 -08:00
39b4ac9968 ls-files and read-tree need core.filemode
ls-files.c and read-tree.c miss the default configuration, in
particular the filemode=false part.  The recent +x bit flip made me
notice that, because git-merge refused to merge anything saying that
git-pull.sh is not up to date.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-08 01:23:52 -08:00
76bca9d1a9 Debian: packaging updates.
Do not scatter txt and html documentation into feature subpackages.
Do place man pages into them.

Capture more cvs stuff into git-cvs package.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-08 01:20:24 -08:00
f2416c27ef Use consistent shell prompts and example style.
Signed-off-by: Jon Loeliger <jdl@freescale.com>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-08 00:23:13 -08:00
d0fde471ab Add --tags documentation, scraped from JC mail.
Signed-off-by: Jon Loeliger <jdl@freescale.com>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-08 00:23:12 -08:00
df8171ccb3 Add support for git-http-push to git-push script
Signed-off-by: Nick Hengeveld <nickh@reactrix.com>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-08 00:23:12 -08:00
067744bd5d Tutorial: do not use 'git resolve'.
Use 'git merge' instead.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-08 00:23:12 -08:00
fb612d54c1 Documentation: fix dependency generation.
The previous rule misses the case where git.txt or tutorial.txt
includes new files.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-08 00:23:12 -08:00
b2d09f063a Add bug isolation howto, scraped from Linus.
Signed-off-by: Jon Loeliger <jdl@freescale.com>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-07 22:18:48 -08:00
77131db585 Merge branch 'master' 2005-11-07 18:23:45 -08:00
390cb0c17a Ignore more generated files.
List new commands cvsexportcommit and http-push to .gitignore list.
Also cover the test programs (test-date and test-delta).

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-07 18:23:10 -08:00
a5ae8e64cf Fix documentation dependency generation.
Documentation/Makefile spent a lot of time to generate include
dependencies, which was quite noticeable especially during "make clean".

Rewrite it to generate just a single dependency file.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-07 18:21:51 -08:00
79f6ac77d9 Documentation: asciidoc formatting fix for git-cvsexportcommit doc.
Annoyingly enough, asciidoc wants the same number of '=' on the second
line as there are characters on the first line.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-07 17:53:06 -08:00
d1745afa2f merge-recursive: Only print relevant rename messages
It isn't really interesting to know about the renames that have
already been committed to the branch you are working on. Furthermore,
the 'git-apply --stat' at the end of git-(merge|pull) will tell us
about any renames in the other branch.

With this commit only renames which require a file-level merge will
be printed.

Signed-off-by: Fredrik Kuivinen <freku045@student.liu.se>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-07 17:13:10 -08:00
52963a7a3f Do not fail on hierarchical tagnames.
This is a companion patch to 13d1cc3604
commit, which made hierarchical branch name possible.  "git tag
v0.99.9/a" would fail otherwise.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-07 16:34:04 -08:00
92e2eb9c0a Small bugfixes for http-push.c
This patch fixes three things:

- older libexpat does not know about enum XML_Status
- as in my patch for http-fetch, do not rely on a curl result in
	free()d data
- calloc the new_lock structure

Signed-off-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-07 13:29:41 -08:00
0dd276b871 Make http-push smarter about creating remote dirs
Remember object directories known to exist in the remote repo and don't
bother trying to create them.

Signed-off-by: Nick Hengeveld <nickh@reactrix.com>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-07 13:29:39 -08:00
5e0306adfa Introducing: git-cvsexportcommit
A script that can replay commits git into a CVS checkout. Tries to ensure the
sanity of the operation and supports mainly manual usage.

If you are reckless enough, you can ask it to autocommit when everything has
applied cleanly. Combined with a couple more scripts could become part of
a git2cvs gateway.

Should support adds/removes and binary files.

Signed-off-by: Martin Langhoff <martin@catalyst.net.nz>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-07 13:28:37 -08:00
e66ab03fcf Documentation update: use git branch -d foo where applicable
This updates documentation to use git branch -d foo in favour of
rm .git/refs/heads/foo

Signed-off-by: Kai Ruemmler <kai.ruemmler@gmx.net>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-07 13:28:31 -08:00
31b9755a65 Recover dropped +x bit from git-pull.sh by accident.
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-07 12:52:07 -08:00
7141b3b780 Merge branch 'master' 2005-11-06 23:33:38 -08:00
44760f1d55 Documentation: talk about guts of merge in tutorial.
While discussing Jon's ASCII art on merge operations with him, I
realized that the tutorial stops talking about the plumbing
details halfway.  So fill in the gory details, and update the
examples to use 'git-merge', not 'git-resolve'.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-06 23:32:33 -08:00
93d69d8691 Refactored merge options into separate merge-options.txt.
Refactored fetch options into separate fetch-options.txt.
Made git-merge use merge-options.
Made git-fetch use fetch-options.
Made git-pull use merge-options and fetch-options.
Added --help option to git-pull and git-format-patch scripts.
Rewrote Documentation/Makefile to dynamically determine
include dependencies.

Signed-off-by: Jon Loeliger <jdl@freescale.com>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-06 23:32:04 -08:00
72e5890b68 GIT 0.99.9e
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-06 18:57:40 -08:00
90279074ca http-fetch: do not use curl_message after releasing it
When curl_message is released using curl_multi_remove_handle(), it's
contents are undefined. Therefore, get the information before releasing it.

Signed-off-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-06 18:31:47 -08:00
67ffdf4c0a Allow GIT_DIR to be an absolute path
This fixes a problem in safe_create_leading_directories() when the
argument starts with a '/' (i.e. the path is absolute).

Signed-off-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-06 18:31:46 -08:00
bee8e79da0 http-push.c: include with angle bracket, not dq.
Do not search the current directory when including expat.h, since it
is not supplied by git.

Signed-off-by: Paul Collins <paul@briny.ondioline.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-06 18:31:46 -08:00
95d117b605 Set up remotes/origin to track all remote branches.
This implements the idea Daniel Barkalow came up with, to match
the remotes/origin created by clone by default to the workflow I
use myself in my guinea pig repository, to have me eat my own
dog food.

We probably would want to use either .git/refs/local/heads/*
(idea by Linus) or .git/refs/heads/origin/* instead to reduce
the local ref namespace pollution.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-06 18:17:14 -08:00
f179044862 git-status: do not mark unmerged paths as committable.
An unmerged path appears as both "Updated but not checked in" list,
and "Changed but not updated" list.  We are not going to commit that
path until it is resolved, so remove it from the former list.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-06 17:37:40 -08:00
fcbc3083e3 ls-files: --others should not say unmerged paths are unknown.
Jon Loeliger noticed that an unmerged path appears as
"Untracked" in git-status output, even though we show the same
path as updated/changed.  Since --others means "we have not told
git about that path", we should not show unmerged paths --
obviously, git knows about them; it just does not know what we
want to do about them yet.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-06 17:26:31 -08:00
0cfddacdcc Use fink/darwinport paths for OSX
There's no standard libexpat for OSX, so if you install it
after-market, it can end up in various directories.  Give
paths used by fink and darwinports by default to CFLAGS.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-06 10:52:48 -08:00
bb73d73c08 Refactor merge strategies into separate includable file.
Signed-off-by: Jon Loeliger <jdl@freescale.com>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-06 10:31:48 -08:00
3402f1d6a3 Document expat dependency when using http-push.
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-06 10:21:06 -08:00
4ea836dba9 Merge in http-push first stage. 2005-11-06 01:27:15 -08:00
75187c9deb Refresh the remote lock if it is about to expire
Refresh the remote lock if it is about to expire

Signed-off-by: Nick Hengeveld <nickh@reactrix.com>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-06 01:14:45 -08:00
26349b2e5e Improve lock handling
Improve lock handling: parse the server response for the timeout, owner,
and lock token

Signed-off-by: Nick Hengeveld <nickh@reactrix.com>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-06 01:14:45 -08:00
0772b9a633 Support remote references with slashes in their names
Support remote references with slashes in their names

Signed-off-by: Nick Hengeveld <nickh@reactrix.com>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-06 01:14:45 -08:00
c17fb6ee07 Verify remote packs, speed up pending request queue
Verify that remote packs exist before using the pack index, add requests to
the beginning of the queue to locate pending requests faster.

Signed-off-by: Nick Hengeveld <nickh@reactrix.com>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-06 01:14:44 -08:00
58e60dd203 Add support for pushing to a remote repository using HTTP/DAV
Add support for pushing to a remote repository using HTTP/DAV

Signed-off-by: Nick Hengeveld <nickh@reactrix.com>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-06 01:14:44 -08:00
c0a2ed1b49 Debian: test build.
Update version number in changelog to match the 0.99.9.GIT version
number, to allow building private deb from wip.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-06 01:12:33 -08:00
9eba845f20 Further Debian split fixes.
The doc installation was flattened, breaking links to howto/.
Silly cut&paste error made git-doc depend on tk8.4.  Doh.
Move most of the documentation (except manuals) to git-doc.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-06 01:12:32 -08:00
54c2533da0 Install asciidoc sources as well.
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-06 01:12:32 -08:00
d071e8dbb6 Package split: Debian.
As discussed on the list, split the foreign SCM interoperability
packages and documentation from the git-core binary package.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-06 01:12:31 -08:00
12aa7456c9 Simplify CFLAGS/DEFINES in Makefile
I think the original intention was to make CFLAGS overridable
from the make command line, but somehow we ended up accumulating
conditional makefile sections that wrongly appends values to
CFLAGs.  These assignments do not work when the user actually
override them from the make command line!

DEFINES are handled the same way; it was seemingly overridable,
but the makefile sections had assignments, which meant
overriding it from the command line broke things.

This simplifies things by limiting the internal futzing to
ALL_CFLAGS, and by removing DEFINES altogether.  Overriding
CFLAGS from the command line should start working with this
change.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-06 01:12:31 -08:00
9e5d2b4096 git-fetch: fail if specified refspec does not match remote.
'git-fetch remote no-such-ref' succeeded without fetching any
ref from the remote.  Detect such case and report an error.

Note that this makes 'git-fetch remote master master' to fail,
because the remote branch 'master' matches the first refspec,
and the second refspec is left unmatched, which is detected by
the error checking logic.  This is somewhat unintuitive, but
giving the same refspec more than once to git-fetch is useless
in any case so it should not be much of a problem.  I'd accept a
patch to change this if somebody cares enough, though.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-06 00:26:21 -08:00
4607166d07 Documentation: pull/clone ref mapping clarification.
Josef Weidendorfer points out that git-clone documentation does not
mention the initial copying of remote branch heads into corresponding
local branches.  Also clarify the purpose of the ref mappings description
in the "remotes" file and recommended workflow.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-06 00:26:21 -08:00
b748421aaa git-format-patch: silly typo fix.
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-06 00:21:45 -08:00
b52d9f9ba7 test: t4102-apply-rename fails with strict umask.
We checked the result of patch application for full permission bits,
when the only thing we cared about was to make sure the executable
bit was correctly set.

Noticed by Peter Baumann.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-05 13:08:18 -08:00
d5bc7eecbb GIT v0.99.7d
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-09-25 00:41:15 -07:00
cfd8aefd4b Merge branch 'fixes' 2005-09-25 00:32:06 -07:00
00d8bbd3c4 GIT 0.99.7c
Contains the following post-0.99.7b fixes:

 - rsh.c string termination fix by H. Peter Anvin
 - further fetch fixes by Sergey Vlasov
 - diff-tree documentation by Robert Watson.
 - 'git diff --cached' synonymous to 'git diff --cached HEAD'.
 - subprocess.py licensing status clarification.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-09-24 11:38:43 -07:00
25a67553ea Really ignore generated distribution material.
Signed-off-by: Junio C Hamano <junkio@cox.net>
(cherry picked from e558e33b7b commit)
2005-09-24 11:38:04 -07:00
a61399b5fb Merge 'fixes' branch
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-09-23 18:51:02 -07:00
990f856a62 GIT 0.99.7b
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-09-22 21:53:33 -07:00
d6179f56f8 Merge branch 'fixes' 2005-09-22 21:52:34 -07:00
089f20dce1 Clarify dual license status of subprocess.py file.
The author of the file we stole from Python 2.4 distribution, Peter
Astrand <astrand@lysator.liu.se>, OK'ed to add this at the end of the
licensing terms section of the file:

    Use of this file within git is permitted under GPLv2.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-09-21 00:58:32 -07:00
9f25c7bd5c Merge branch 'fixes' 2005-09-21 00:45:25 -07:00
dc4393cba3 GIT 0.99.7a
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-09-19 19:50:09 -07:00
176 changed files with 8283 additions and 2239 deletions

8
.gitignore vendored
View File

@ -19,6 +19,7 @@ git-commit
git-commit-tree
git-convert-objects
git-count-objects
git-cvsexportcommit
git-cvsimport
git-daemon
git-diff
@ -36,10 +37,12 @@ git-get-tar-commit-id
git-grep
git-hash-object
git-http-fetch
git-http-push
git-index-pack
git-init-db
git-local-fetch
git-log
git-lost-found
git-ls-files
git-ls-remote
git-ls-tree
@ -58,6 +61,7 @@ git-mktag
git-name-rev
git-mv
git-octopus
git-pack-redundant
git-pack-objects
git-parse-remote
git-patch-id
@ -70,8 +74,8 @@ git-read-tree
git-rebase
git-receive-pack
git-relink
git-rename
git-repack
git-repo-config
git-request-pull
git-reset
git-resolve
@ -107,6 +111,8 @@ git-verify-tag
git-whatchanged
git-write-tree
git-core-*/?*
test-date
test-delta
*.tar.gz
*.dsc
*.deb

View File

@ -3,3 +3,4 @@
*.1
*.7
howto-index.txt
doc.dep

View File

@ -49,22 +49,22 @@ install: man
$(INSTALL) $(DOC_MAN1) $(DESTDIR)/$(man1)
$(INSTALL) $(DOC_MAN7) $(DESTDIR)/$(man7)
# 'include' dependencies
$(patsubst %.txt,%.1,$(wildcard git-diff-*.txt)): \
diff-format.txt diff-options.txt
$(patsubst %.txt,%.html,$(wildcard git-diff-*.txt)): \
diff-format.txt diff-options.txt
$(patsubst %,%.1,git-fetch git-pull git-push): pull-fetch-param.txt
$(patsubst %,%.html,git-fetch git-pull git-push): pull-fetch-param.txt
#
# Determine "include::" file references in asciidoc files.
#
doc.dep : $(wildcard *.txt) build-docdep.perl
rm -f $@+ $@
perl ./build-docdep.perl >$@+
mv $@+ $@
$(patsubst %,%.1,git-merge git-pull): merge-pull-opts.txt
$(patsubst %,%.html,git-merge git-pull): merge-pull-opts.txt
-include doc.dep
git.7: ../README
clean:
rm -f *.xml *.html *.1 *.7 howto-index.txt howto/*.html
rm -f *.xml *.html *.1 *.7 howto-index.txt howto/*.html doc.dep
%.html : %.txt
asciidoc -b xhtml11 -d manpage -f asciidoc.conf $<

50
Documentation/build-docdep.perl Executable file
View File

@ -0,0 +1,50 @@
#!/usr/bin/perl
my %include = ();
my %included = ();
for my $text (<*.txt>) {
open I, '<', $text || die "cannot read: $text";
while (<I>) {
if (/^include::/) {
chomp;
s/^include::\s*//;
s/\[\]//;
$include{$text}{$_} = 1;
$included{$_} = 1;
}
}
close I;
}
# Do we care about chained includes???
my $changed = 1;
while ($changed) {
$changed = 0;
while (my ($text, $included) = each %include) {
for my $i (keys %$included) {
# $text has include::$i; if $i includes $j
# $text indirectly includes $j.
if (exists $include{$i}) {
for my $j (keys %{$include{$i}}) {
if (!exists $include{$text}{$j}) {
$include{$text}{$j} = 1;
$included{$j} = 1;
$changed = 1;
}
}
}
}
}
}
while (my ($text, $included) = each %include) {
if (! exists $included{$text} &&
(my $base = $text) =~ s/\.txt$//) {
my ($suffix) = '1';
if ($base eq 'git') {
$suffix = '7'; # yuck...
}
print "$base.html $base.$suffix : ", join(" ", keys %$included), "\n";
}
}

View File

@ -8,13 +8,13 @@ git-diff-index <tree-ish>::
compares the <tree-ish> and the files on the filesystem.
git-diff-index --cached <tree-ish>::
compares the <tree-ish> and the cache.
compares the <tree-ish> and the index.
git-diff-tree [-r] <tree-ish-1> <tree-ish-2> [<pattern>...]::
compares the trees named by the two arguments.
git-diff-files [<pattern>...]::
compares the cache and the files on the filesystem.
compares the index and the files on the filesystem.
An output line is formatted this way:
@ -47,7 +47,7 @@ That is, from the left to the right:
. an LF or a NUL when '-z' option is used, to terminate the record.
<sha1> is shown as all 0's if a file is new on the filesystem
and it is out of sync with the cache.
and it is out of sync with the index.
Example:
@ -81,7 +81,7 @@ The "diff" formatting options can be customized via the
environment variable 'GIT_DIFF_OPTS'. For example, if you
prefer context diff:
GIT_DIFF_OPTS=-c git-diff-index -p $(cat .git/HEAD)
GIT_DIFF_OPTS=-c git-diff-index -p HEAD
2. When the environment variable 'GIT_EXTERNAL_DIFF' is set, the
@ -104,7 +104,7 @@ where:
The file parameters can point at the user's working file
(e.g. `new-file` in "git-diff-files"), `/dev/null` (e.g. `old-file`
when a new file is added), or a temporary file (e.g. `old-file` in the
cache). 'GIT_EXTERNAL_DIFF' should not worry about unlinking the
index). 'GIT_EXTERNAL_DIFF' should not worry about unlinking the
temporary file --- it is removed when 'GIT_EXTERNAL_DIFF' exits.
For a path that is unmerged, 'GIT_EXTERNAL_DIFF' is called with 1

View File

@ -13,6 +13,11 @@
--name-status::
Show only names and status of changed files.
--full-index::
Instead of the first handful characters, show full
object name of pre- and post-image blob on the "index"
line when generating a patch format output.
-B::
Break complete rewrite changes into pairs of delete and create.
@ -50,7 +55,7 @@
<orderfile>, which has one shell glob pattern per line.
-R::
Swap two inputs; that is, show differences from cache or
Swap two inputs; that is, show differences from index or
on-disk file to tree contents.
For more detailed explanation on these common options, see also

View File

@ -0,0 +1,19 @@
-a, \--append::
Append ref names and object names of fetched refs to the
existing contents of `.git/FETCH_HEAD`. Without this
option old data in `.git/FETCH_HEAD` will be overwritten.
-f, \--force::
-t, \--tags::
By default, the git core utilities will not fetch and store
tags under the same name as the remote repository; ask it
to do so using `--tags`. Using this option will bound the
list of objects pulled to the remote tags. Commits in branches
beyond the tags will be ignored.
-u, \--update-head-ok::
By default `git-fetch` refuses to update the head which
corresponds to the current branch. This flag disables the
check. Note that fetching into the current branch will not
update the index and working directory, so use it with care.

View File

@ -8,8 +8,8 @@ git-am - Apply a series of patches in a mailbox
SYNOPSIS
--------
'git-am' [--signoff] [--dotest=<dir>] [--utf8] [--3way] <mbox>...
'git-am' [--skip]
'git-am' [--signoff] [--dotest=<dir>] [--utf8] [--binary] [--3way] <mbox>...
'git-am' [--skip | --resolved]
DESCRIPTION
-----------
@ -31,6 +31,10 @@ OPTIONS
Pass `--utf8` and `--keep` flags to `git-mailinfo` (see
gitlink:git-mailinfo[1]).
--binary::
Pass `--allow-binary-replacement` flag to `git-apply`
(see gitlink:git-apply[1]).
--3way::
When the patch does not apply cleanly, fall back on
3-way merge, if the patch records the identity of blobs
@ -44,6 +48,13 @@ OPTIONS
--interactive::
Run interactively, just like git-applymbox.
--resolved::
After a patch failure (e.g. attempting to apply
conflicting patch), the user has applied it by hand and
the index file stores the result of the application.
Make a commit using the authorship and commit log
extracted from the e-mail message and the current index
file, and continue.
DISCUSSION
----------
@ -56,12 +67,9 @@ recover from this in one of two ways:
. skip the current one by re-running the command with '--skip'
option.
. hand resolve the conflict in the working directory, run 'git
diff HEAD' to extract the merge result into a patch form and
replacing the patch in .dotest/patch file. After doing this,
run `git-reset --hard HEAD` to bring the working tree to the
state before half-applying the patch, then re-run the command
without any options.
. hand resolve the conflict in the working directory, and update
the index file to bring it in a state that the patch should
have produced. Then run the command with '--resume' option.
The command refuses to process new mailboxes while `.dotest`
directory exists, so if you decide to start over from scratch,

View File

@ -8,7 +8,7 @@ git-apply - Apply patch on a git index file and a work tree
SYNOPSIS
--------
'git-apply' [--stat] [--numstat] [--summary] [--check] [--index] [--apply] [--index-info] [-z] [<patch>...]
'git-apply' [--stat] [--numstat] [--summary] [--check] [--index] [--apply] [--no-add] [--index-info] [--allow-binary-replacement] [-z] [<patch>...]
DESCRIPTION
-----------
@ -72,6 +72,23 @@ OPTIONS
patch. Give this flag after those flags to also apply
the patch.
--no-add::
When applying a patch, ignore additions made by the
patch. This can be used to extract common part between
two files by first running `diff` on them and applying
the result with this option, which would apply the
deletion part but not addition part.
--allow-binary-replacement::
When applying a patch, which is a git-enhanced patch
that was prepared to record the pre- and post-image object
name in full, and the path being patched exactly matches
the object the patch applies to (i.e. "index" line's
pre-image object name is what is in the working tree),
and the post-image object is available in the object
database, use the post-image object as the patch
result. This allows binary files to be patched in a
very limited way.
Author
------

View File

@ -3,11 +3,11 @@ git-branch(1)
NAME
----
git-branch - Create a new branch.
git-branch - Create a new branch, or remove an old one.
SYNOPSIS
--------
'git-branch' [<branchname> [start-point]]
'git-branch' [-d | -D] [<branchname> [start-point]]
DESCRIPTION
-----------
@ -19,11 +19,18 @@ created, otherwise it will be created at the current HEAD.
OPTIONS
-------
-d::
Delete a branch. The branch must be fully merged.
-D::
Delete a branch irrespective of its index status.
<branchname>::
The name of the branch to create.
The name of the branch to create or delete.
start-point::
Where to create the branch; defaults to HEAD.
Where to create the branch; defaults to HEAD. This
option has no meaning with -d and -D.
Author
------

View File

@ -3,7 +3,7 @@ git-checkout-index(1)
NAME
----
git-checkout-index - Copy files from the cache to the working directory
git-checkout-index - Copy files from the index to the working directory
SYNOPSIS
@ -13,26 +13,26 @@ SYNOPSIS
DESCRIPTION
-----------
Will copy all files listed from the cache to the working directory
Will copy all files listed from the index to the working directory
(not overwriting existing files).
OPTIONS
-------
-u::
-u|--index::
update stat information for the checked out entries in
the cache file.
the index file.
-q::
be quiet if files exist or are not in the cache
-q|--quiet::
be quiet if files exist or are not in the index
-f::
-f|--force::
forces overwrite of existing files
-a::
checks out all files in the cache. Cannot be used
-a|--all::
checks out all files in the index. Cannot be used
together with explicit filenames.
-n::
-n|--no-create::
Don't checkout new files, only refresh files already checked
out.
@ -57,7 +57,7 @@ supposed to be able to do things like:
which will force all existing `*.h` files to be replaced with their
cached copies. If an empty command line implied "all", then this would
force-refresh everything in the cache, which was not the point.
force-refresh everything in the index, which was not the point.
To update and refresh only the files already checked out:
@ -74,7 +74,7 @@ desired tree into the index, and do a
git-checkout-index --prefix=git-export-dir/ -a
and git-checkout-index will "export" the cache into the specified
and git-checkout-index will "export" the index into the specified
directory.
NOTE The final "/" is important. The exported name is literally just

View File

@ -8,11 +8,26 @@ git-clone - Clones a repository.
SYNOPSIS
--------
'git-clone' [-l [-s]] [-q] [-n] [-u <upload-pack>] <repository> <directory>
'git-clone' [-l [-s]] [-q] [-n] [-u <upload-pack>] <repository> [<directory>]
DESCRIPTION
-----------
Clones a repository into a newly created directory.
Clones a repository into a newly created directory. All remote
branch heads are copied under `$GIT_DIR/refs/heads/`, except
that the remote `master` is also copied to `origin` branch.
In addition, `$GIT_DIR/remotes/origin` file is set up to have
this line:
Pull: master:origin
This is to help the typical workflow of working off of the
remote `master` branch. Every time `git pull` without argument
is run, the progress on the remote `master` branch is tracked by
copying it into the local `origin` branch, and merged into the
branch you are currently working on. Remote branches other than
`master` are also added there to be tracked.
OPTIONS
-------
@ -28,9 +43,10 @@ OPTIONS
--shared::
-s::
When the repository to clone is on the local machine,
instead of using hard links automatically setup
instead of using hard links, automatically setup
.git/objects/info/alternatives to share the objects
with the source repository
with the source repository. The resulting repository
starts out without any object of its own.
--quiet::
-q::
@ -49,13 +65,14 @@ OPTIONS
<repository>::
The (possibly remote) repository to clone from. It can
be an "rsync://host/dir" URL, an "http://host/dir" URL,
or [<host>:]/dir notation that is used by 'git-clone-pack'.
Currently http transport is not supported.
be any URL git-fetch supports.
<directory>::
The name of a new directory to be cloned into. It is an
error to specify an existing directory.
The name of a new directory to clone into. The "humanish"
part of the source repository is used if no directory is
explicitly given ("repo" for "/path/to/repo.git" and "foo"
for "host.xz:foo/.git"). Cloning into an existing directory
is not allowed.
Author
------
@ -63,7 +80,7 @@ Written by Linus Torvalds <torvalds@osdl.org>
Documentation
--------------
Documentation by Junio C Hamano.
Documentation by Junio C Hamano and the git-list <git@vger.kernel.org>.
GIT

View File

@ -8,7 +8,7 @@ git-commit-tree - Creates a new commit object
SYNOPSIS
--------
'git-commit-tree' <tree> [-p <parent commit>]\ < changelog
'git-commit-tree' <tree> [-p <parent commit>]\* < changelog
DESCRIPTION
-----------
@ -26,8 +26,9 @@ to get there.
Normally a commit would identify a new "HEAD" state, and while git
doesn't care where you save the note about that state, in practice we
tend to just write the result to the file `.git/HEAD`, so that we can
always see what the last committed state was.
tend to just write the result to the file that is pointed at by
`.git/HEAD`, so that we can always see what the last committed
state was.
OPTIONS
-------

View File

@ -0,0 +1,56 @@
git-cvsexportcommit(1)
======================
NAME
----
git-cvsexportcommit - Export a commit to a CVS checkout
SYNOPSIS
--------
git-cvsapplycommmit.perl
[ -h ] [ -v ] [ -c ] [ -p ] [PARENTCOMMIT] COMMITID
DESCRIPTION
-----------
Exports a commit from GIT to a CVS checkout, making it easier
to merge patches from a git repository into a CVS repository.
Execute it from the root of the CVS working copy. GIT_DIR must be defined.
It does its best to do the safe thing, it will check that the files are
unchanged and up to date in the CVS checkout, and it will not autocommit
by default.
Supports file additions, removals, and commits that affect binary files.
If the commit is a merge commit, you must tell git-cvsapplycommit what parent
should the changeset be done against.
OPTIONS
-------
-c::
Commit automatically if the patch applied cleanly. It will not
commit if any hunks fail to apply or there were other problems.
-p::
Be pedantic (paranoid) when applying patches. Invokes patch with
--fuzz=0
-v::
Verbose.
Author
------
Written by Martin Langhoff <martin@catalyst.net.nz>
Documentation
--------------
Documentation by Martin Langhoff <martin@catalyst.net.nz>
GIT
---
Part of the gitlink:git[7] suite

View File

@ -35,7 +35,7 @@ OPTIONS
-i::
Import-only: don't perform a checkout after importing. This option
ensures the working directory and cache remain untouched and will
ensures the working directory and index remain untouched and will
not create them if they do not exist.
-k::

View File

@ -8,7 +8,7 @@ git-daemon - A really simple server for git repositories.
SYNOPSIS
--------
'git-daemon' [--verbose] [--syslog] [--inetd | --port=n] [--export-all]
[--timeout=n] [--init-timeout=n] [directory...]
[--timeout=n] [--init-timeout=n] [--strict-paths] [directory...]
DESCRIPTION
-----------
@ -29,13 +29,19 @@ This is ideally suited for read-only updates, ie pulling from git repositories.
OPTIONS
-------
--strict-paths::
Match paths exactly (i.e. don't allow "/foo/repo" when the real path is
"/foo/repo.git" or "/foo/repo/.git") and don't do user-relative paths.
git-daemon will refuse to start when this option is enabled and no
whitelist is specified.
--export-all::
Allow pulling from all directories that look like GIT repositories
(have the 'objects' subdirectory and a 'HEAD' file), even if they
(have the 'objects' and 'refs' subdirectories), even if they
do not have the 'git-daemon-export-ok' file.
--inetd::
Have the server run as an inetd service.
Have the server run as an inetd service. Implies --syslog.
--port::
Listen on an alternative port.
@ -57,9 +63,15 @@ OPTIONS
--verbose::
Log details about the incoming connections and requested files.
<directory>::
A directory to add to the whitelist of allowed directories. Unless
--strict-paths is specified this will also include subdirectories
of each named directory.
Author
------
Written by Linus Torvalds <torvalds@osdl.org> and YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Written by Linus Torvalds <torvalds@osdl.org>, YOSHIFUJI Hideaki
<yoshfuji@linux-ipv6.org> and the git-list <git@vger.kernel.org>
Documentation
--------------

View File

@ -3,7 +3,7 @@ git-diff-files(1)
NAME
----
git-diff-files - Compares files in the working tree and the cache
git-diff-files - Compares files in the working tree and the index
SYNOPSIS
@ -12,9 +12,9 @@ SYNOPSIS
DESCRIPTION
-----------
Compares the files in the working tree and the cache. When paths
Compares the files in the working tree and the index. When paths
are specified, compares only those named paths. Otherwise all
entries in the cache are compared. The output format is the
entries in the index are compared. The output format is the
same as "git-diff-index" and "git-diff-tree".
OPTIONS

View File

@ -3,7 +3,7 @@ git-diff-index(1)
NAME
----
git-diff-index - Compares content and mode of blobs between the cache and repository
git-diff-index - Compares content and mode of blobs between the index and repository
SYNOPSIS
@ -13,10 +13,10 @@ SYNOPSIS
DESCRIPTION
-----------
Compares the content and mode of the blobs found via a tree
object with the content of the current cache and, optionally
object with the content of the current index and, optionally
ignoring the stat state of the file on disk. When paths are
specified, compares only those named paths. Otherwise all
entries in the cache are compared.
entries in the index are compared.
OPTIONS
-------
@ -49,22 +49,22 @@ Cached Mode
-----------
If '--cached' is specified, it allows you to ask:
show me the differences between HEAD and the current cache
show me the differences between HEAD and the current index
contents (the ones I'd write with a "git-write-tree")
For example, let's say that you have worked on your working directory, updated
some files in the cache and are ready to commit. You want to see eactly
some files in the index and are ready to commit. You want to see eactly
*what* you are going to commit is without having to write a new tree
object and compare it that way, and to do that, you just do
git-diff-index --cached $(cat .git/HEAD)
git-diff-index --cached HEAD
Example: let's say I had renamed `commit.c` to `git-commit.c`, and I had
done an "git-update-index" to make that effective in the index file.
"git-diff-files" wouldn't show anything at all, since the index file
matches my working directory. But doing a "git-diff-index" does:
torvalds@ppc970:~/git> git-diff-index --cached $(cat .git/HEAD)
torvalds@ppc970:~/git> git-diff-index --cached HEAD
-100644 blob 4161aecc6700a2eb579e842af0b7f22b98443f74 commit.c
+100644 blob 4161aecc6700a2eb579e842af0b7f22b98443f74 git-commit.c
@ -92,13 +92,13 @@ which is obviously a very useful question too, since that tells you what
you *could* commit. Again, the output matches the "git-diff-tree -r"
output to a tee, but with a twist.
The twist is that if some file doesn't match the cache, we don't have
The twist is that if some file doesn't match the index, we don't have
a backing store thing for it, and we use the magic "all-zero" sha1 to
show that. So let's say that you have edited `kernel/sched.c`, but
have not actually done a "git-update-index" on it yet - there is no
"object" associated with the new state, and you get:
torvalds@ppc970:~/v2.6/linux> git-diff-index $(cat .git/HEAD )
torvalds@ppc970:~/v2.6/linux> git-diff-index HEAD
*100644->100664 blob 7476bb......->000000...... kernel/sched.c
ie it shows that the tree has changed, and that `kernel/sched.c` has is
@ -110,7 +110,7 @@ NOTE: As with other commands of this type, "git-diff-index" does not
actually look at the contents of the file at all. So maybe
`kernel/sched.c` hasn't actually changed, and it's just that you
touched it. In either case, it's a note that you need to
"git-upate-cache" it to make the cache be in sync.
"git-upate-index" it to make the index be in sync.
NOTE: You can have a mixture of files show up as "has been updated"
and "is still dirty in the working directory" together. You can always

View File

@ -8,7 +8,7 @@ git-diff-tree - Compares the content and mode of blobs found via two tree object
SYNOPSIS
--------
'git-diff-tree' [--stdin] [-m] [-s] [-v] [--pretty] [-t] [-r] [--root] [<common diff options>] <tree-ish> [<tree-ish>] [<path>...]
'git-diff-tree' [--stdin] [-m] [-s] [-v] [--no-commit-id] [--pretty] [-t] [-r] [--root] [<common diff options>] <tree-ish> [<tree-ish>] [<path>...]
DESCRIPTION
-----------
@ -74,6 +74,10 @@ separated with a single space are given.
commit message. Without "=<style>", it defaults to
medium.
--no-commit-id::
git-diff-tree outputs a line with the commit ID when
applicable. This flag suppressed the commit ID output.
Limiting Output
---------------

View File

@ -8,7 +8,7 @@ git-fetch - Download objects and a head from another repository.
SYNOPSIS
--------
'git-fetch' <repository> <refspec>...
'git-fetch' <options> <repository> <refspec>...
DESCRIPTION
@ -17,24 +17,16 @@ Fetches named heads or tags from another repository, along with
the objects necessary to complete them.
The ref names and their object names of fetched refs are stored
in $GIT_DIR/FETCH_HEAD. This information is left for a later merge
in `.git/FETCH_HEAD`. This information is left for a later merge
operation done by "git resolve" or "git octopus".
OPTIONS
-------
include::fetch-options.txt[]
include::pull-fetch-param.txt[]
-a, \--append::
Append ref names and object names of fetched refs to the
existing contents of $GIT_DIR/FETCH_HEAD. Without this
option old data in $GIT_DIR/FETCH_HEAD will be overwritten.
-u, \--update-head-ok::
By default 'git-fetch' refuses to update the head which
corresponds to the current branch. This flag disables the
check. Note that fetching into the current branch will not
update the index and working directory, so use it with care.
SEE ALSO

View File

@ -33,7 +33,7 @@ index file and all SHA1 references in .git/refs/* as heads.
Report tags.
--cache::
Consider any object recorded in the cache also as a head node for
Consider any object recorded in the index also as a head node for
an unreachability trace.
--standalone::
@ -68,7 +68,7 @@ that aren't readable from any of the specified head nodes.
So for example
git-fsck-objects --unreachable $(cat .git/HEAD .git/refs/heads/*)
git-fsck-objects --unreachable HEAD $(cat .git/refs/heads/*)
will do quite a _lot_ of verification on the tree. There are a few
extra validity tests to be added (make sure that tree objects are
@ -125,7 +125,7 @@ GIT_OBJECT_DIRECTORY::
used to specify the object database root (usually $GIT_DIR/objects)
GIT_INDEX_FILE::
used to specify the index file of the cache
used to specify the index file of the index
GIT_ALTERNATE_OBJECT_DIRECTORIES::
used to specify additional object database roots (usually unset)

View File

@ -16,7 +16,7 @@ Computes the object ID value for an object with specified type
with the contents of the named file (which can be outside of the
work tree), and optionally writes the resulting object into the
object database. Reports its object ID to its standard output.
This is used by "git-cvsimport" to update the cache
This is used by "git-cvsimport" to update the index
without modifying files in the work tree. When <type> is not
specified, it defaults to "blob".

View File

@ -0,0 +1,89 @@
git-http-push(1)
================
NAME
----
git-http-push - Push missing objects using HTTP/DAV.
SYNOPSIS
--------
'git-http-push' [--complete] [--force] [--verbose] <url> <ref> [<ref>...]
DESCRIPTION
-----------
Sends missing objects to remote repository, and updates the
remote branch.
OPTIONS
-------
--complete::
Do not assume that the remote repository is complete in its
current state, and verify all objects in the entire local
ref's history exist in the remote repository.
--force::
Usually, the command refuses to update a remote ref that
is not an ancestor of the local ref used to overwrite it.
This flag disables the check. What this means is that
the remote repository can lose commits; use it with
care.
--verbose::
Report the list of objects being walked locally and the
list of objects successfully sent to the remote repository.
<ref>...:
The remote refs to update.
Specifying the Refs
-------------------
A '<ref>' specification can be either a single pattern, or a pair
of such patterns separated by a colon ":" (this means that a ref name
cannot have a colon in it). A single pattern '<name>' is just a
shorthand for '<name>:<name>'.
Each pattern pair consists of the source side (before the colon)
and the destination side (after the colon). The ref to be
pushed is determined by finding a match that matches the source
side, and where it is pushed is determined by using the
destination side.
- It is an error if <src> does not match exactly one of the
local refs.
- If <dst> does not match any remote ref, either
* it has to start with "refs/"; <dst> is used as the
destination literally in this case.
* <src> == <dst> and the ref that matched the <src> must not
exist in the set of remote refs; the ref matched <src>
locally is used as the name of the destination.
Without '--force', the <src> ref is stored at the remote only if
<dst> does not exist, or <dst> is a proper subset (i.e. an
ancestor) of <src>. This check, known as "fast forward check",
is performed in order to avoid accidentally overwriting the
remote ref and lose other peoples' commits from there.
With '--force', the fast forward check is disabled for all refs.
Optionally, a <ref> parameter can be prefixed with a plus '+' sign
to disable the fast-forward check only on that ref.
Author
------
Written by Nick Hengeveld <nickh@reactrix.com>
Documentation
--------------
Documentation by Nick Hengeveld
GIT
---
Part of the gitlink:git[7] suite

View File

@ -20,7 +20,7 @@ This manual page describes only the most frequently used options.
OPTIONS
-------
--pretty=<format>:
--pretty=<format>::
Controls the way the commit log is formatted.
--max-count=<n>::

View File

@ -0,0 +1,78 @@
git-lost-found(1)
=================
NAME
----
git-lost-found - Recover lost refs that luckily have not yet been pruned.
SYNOPSIS
--------
'git-lost-found'
DESCRIPTION
-----------
Finds dangling commits and tags from the object database, and
creates refs to them in .git/lost-found/ directory. Commits and
tags that dereference to commits go to .git/lost-found/commit
and others are stored in .git/lost-found/other directory.
OUTPUT
------
One line description from the commit and tag found along with
their object name are printed on the standard output.
EXAMPLE
-------
Suppose you run 'git tag -f' and mistyped the tag to overwrite.
The ref to your tag is overwritten, but until you run 'git
prune', it is still there.
------------
$ git lost-found
[1ef2b196d909eed523d4f3c9bf54b78cdd6843c6] GIT 0.99.9c
...
------------
Also you can use gitk to browse how they relate to each other
and existing (probably old) tags.
------------
$ gitk $(cd .git/lost-found/commit && echo ??*)
------------
After making sure that it is the object you are looking for, you
can reconnect it to your regular .git/refs hierarchy.
------------
$ git cat-file -t 1ef2b196
tag
$ git cat-file tag 1ef2b196
object fa41bbce8e38c67a218415de6cfa510c7e50032a
type commit
tag v0.99.9c
tagger Junio C Hamano <junkio@cox.net> 1131059594 -0800
GIT 0.99.9c
This contains the following changes from the "master" branch, since
...
$ git update-ref refs/tags/not-lost-anymore 1ef2b196
$ git rev-parse not-lost-anymore
1ef2b196d909eed523d4f3c9bf54b78cdd6843c6
------------
Author
------
Written by Junio C Hamano 濱野 純 <junkio@cox.net>
Documentation
--------------
Documentation by Junio C Hamano and the git-list <git@vger.kernel.org>.
GIT
---
Part of the gitlink:git[7] suite

View File

@ -3,7 +3,7 @@ git-ls-files(1)
NAME
----
git-ls-files - Information about files in the cache/working directory
git-ls-files - Information about files in the index/working directory
SYNOPSIS

View File

@ -12,7 +12,7 @@ SYNOPSIS
DESCRIPTION
-----------
This looks up the <file>(s) in the cache and, if there are any merge
This looks up the <file>(s) in the index and, if there are any merge
entries, passes the SHA1 hash for those files as arguments 1, 2, 3 (empty
argument if no file), and <file> as argument 4. File modes for the three
files are passed as arguments 5, 6 and 7.
@ -23,7 +23,7 @@ OPTIONS
Interpret all following arguments as filenames.
-a::
Run merge against all files in the cache that need merging.
Run merge against all files in the index that need merging.
-o::
Instead of stopping at the first failed merge, do all of them

View File

@ -19,7 +19,7 @@ which drives multiple merge strategy scripts.
OPTIONS
-------
include::merge-pull-opts.txt[]
include::merge-options.txt[]
<msg>::
The commit message to be used for the merge commit (in case
@ -34,6 +34,8 @@ include::merge-pull-opts.txt[]
least one <remote>. Specifying more than one <remote>
obviously means you are trying an Octopus.
include::merge-strategies.txt[]
SEE ALSO
--------

View File

@ -0,0 +1,58 @@
git-pack-redundant(1)
=====================
NAME
----
git-pack-redundant - Program used to find redundant pack files.
SYNOPSIS
--------
'git-pack-redundant [ --verbose ] [ --alt-odb ] < --all | .pack filename ... >'
DESCRIPTION
-----------
This program computes which packs in your repository
are redundant. The output is suitable for piping to
'xargs rm' if you are in the root of the repository.
git-pack-redundant accepts a list of objects on standard input. Any objects
given will be ignored when checking which packs are required. This makes the
following command useful when wanting to remove packs which contain unreachable
objects.
git-fsck-objects --full --unreachable | cut -d ' ' -f3 | \
git-pack-redundant --all | xargs rm
OPTIONS
-------
--all::
Processes all packs. Any filenames on the commandline are ignored.
--alt-odb::
Don't require objects present in packs from alternate object
directories to be present in local packs.
--verbose::
Outputs some statistics to stderr. Has a small performance penalty.
Author
------
Written by Lukas Sandström <lukass@etek.chalmers.se>
Documentation
--------------
Documentation by Lukas Sandström <lukass@etek.chalmers.se>
See-Also
--------
gitlink:git-pack-objects[1]
gitlink:git-repack[1]
gitlink:git-prune-packed[1]
GIT
---
Part of the gitlink:git[7] suite

View File

@ -23,6 +23,12 @@ compression applied, stored in a single file, with an associated index file.
Packs are used to reduce the load on mirror systems, backup engines, disk storage, etc.
OPTIONS
-------
-n::
Don't actually remove any objects, only show those that would have been
removed.
Author
------
Written by Linus Torvalds <torvalds@osdl.org>

View File

@ -20,53 +20,16 @@ Note that you can use `.` (current directory) as the
<repository> to pull from the local repository -- this is useful
when merging local branches into the current branch.
OPTIONS
-------
include::merge-options.txt[]
include::fetch-options.txt[]
include::pull-fetch-param.txt[]
-a, \--append::
Append ref names and object names of fetched refs to the
existing contents of `$GIT_DIR/FETCH_HEAD`. Without this
option old data in `$GIT_DIR/FETCH_HEAD` will be overwritten.
include::merge-pull-opts.txt[]
MERGE STRATEGIES
----------------
resolve::
This can only resolve two heads (i.e. the current branch
and another branch you pulled from) using 3-way merge
algorithm. It tries to carefully detect criss-cross
merge ambiguities and is considered generally safe and
fast. This is the default merge strategy when pulling
one branch.
recursive::
This can only resolve two heads using 3-way merge
algorithm. When there are more than one common
ancestors that can be used for 3-way merge, it creates a
merged tree of the common ancestores and uses that as
the reference tree for the 3-way merge. This has been
reported to result in fewer merge conflicts without
causing mis-merges by tests done on actual merge commits
taken from Linux 2.6 kernel development history.
Additionally this can detect and handle merges involving
renames.
octopus::
This resolves more than two-head case, but refuses to do
complex merge that needs manual resolution. It is
primarily meant to be used for bundling topic branch
heads together. This is the default merge strategy when
pulling more than one branch.
ours::
This resolves any number of heads, but the result of the
merge is always the current branch head. It is meant to
be used to supersede old development history of side
branches.
include::merge-strategies.txt[]
EXAMPLES
@ -106,7 +69,7 @@ $ git fetch origin master:origin +pu:pu maint:maint
$ git pull . origin
------------------------------------------------
+
Here, a typical `$GIT_DIR/remotes/origin` file from a
Here, a typical `.git/remotes/origin` file from a
`git-clone` operation is used in combination with
command line options to `git-fetch` to first update
multiple branches of the local repository and then
@ -119,7 +82,7 @@ known to have already obtained and made available
all the necessary objects.
Pull of multiple branches from one repository using `$GIT_DIR/remotes` file::
Pull of multiple branches from one repository using `.git/remotes` file::
+
------------------------------------------------
$ cat .git/remotes/origin
@ -132,7 +95,7 @@ $ git checkout master
$ git pull origin
------------------------------------------------
+
Here, a typical `$GIT_DIR/remotes/origin` file from a
Here, a typical `.git/remotes/origin` file from a
`git-clone` operation has been hand-modified to include
the branch-mapping of additional remote and local
heads directly. A single `git-pull` operation while

View File

@ -3,7 +3,7 @@ git-read-tree(1)
NAME
----
git-read-tree - Reads tree information into the directory cache
git-read-tree - Reads tree information into the index
SYNOPSIS
@ -13,11 +13,11 @@ SYNOPSIS
DESCRIPTION
-----------
Reads the tree information given by <tree-ish> into the directory cache,
Reads the tree information given by <tree-ish> into the index,
but does not actually *update* any of the files it "caches". (see:
git-checkout-index)
Optionally, it can merge a tree into the cache, perform a
Optionally, it can merge a tree into the index, perform a
fast-forward (i.e. 2-way) merge, or a 3-way merge, with the -m
flag. When used with -m, the -u flag causes it to also update
the files in the work tree with the result of the merge.
@ -30,6 +30,10 @@ OPTIONS
-m::
Perform a merge, not just a read.
--reset::
Same as -m except that unmerged entries will be silently ignored.
-u::
After a successful merge, update the files in the work
tree with the result of the merge.
@ -59,10 +63,10 @@ provided.
Single Tree Merge
~~~~~~~~~~~~~~~~~
If only 1 tree is specified, git-read-tree operates as if the user did not
specify '-m', except that if the original cache has an entry for a
specify '-m', except that if the original index has an entry for a
given pathname, and the contents of the path matches with the tree
being read, the stat info from the cache is used. (In other words, the
cache's stat()s take precedence over the merged tree's).
being read, the stat info from the index is used. (In other words, the
index's stat()s take precedence over the merged tree's).
That means that if you do a "git-read-tree -m <newtree>" followed by a
"git-checkout-index -f -u -a", the "git-checkout-index" only checks out
@ -96,7 +100,7 @@ Here are the "carry forward" rules:
-------------------------------------------------------
0 nothing nothing nothing (does not happen)
1 nothing nothing exists use M
2 nothing exists nothing remove path from cache
2 nothing exists nothing remove path from index
3 nothing exists exists use M
clean I==H I==M
@ -109,7 +113,7 @@ Here are the "carry forward" rules:
8 yes N/A no nothing exists fail
9 no N/A no nothing exists fail
10 yes yes N/A exists nothing remove path from cache
10 yes yes N/A exists nothing remove path from index
11 no yes N/A exists nothing fail
12 yes no N/A exists nothing fail
13 no no N/A exists nothing fail
@ -128,7 +132,7 @@ Here are the "carry forward" rules:
20 yes yes no exists exists use M
21 no yes no exists exists fail
In all "keep index" cases, the cache entry stays as in the
In all "keep index" cases, the index entry stays as in the
original index file. If the entry were not up to date,
git-read-tree keeps the copy in the work tree intact when
operating under the -u flag.
@ -233,7 +237,7 @@ This is done to prevent you from losing your work-in-progress
changes. To illustrate, suppose you start from what has been
commited last to your repository:
$ JC=`cat .git/HEAD`
$ JC=`git-rev-parse --verify "HEAD^0"`
$ git-checkout-index -f -u -a $JC
You do random edits, without running git-update-index. And then
@ -245,7 +249,7 @@ since you pulled from him:
Your work tree is still based on your HEAD ($JC), but you have
some edits since. Three-way merge makes sure that you have not
added or modified cache entries since $JC, and if you haven't,
added or modified index entries since $JC, and if you haven't,
then does the right thing. So with the following sequence:
$ git-read-tree -m -u `git-merge-base $JC $LT` $JC $LT

View File

@ -1,32 +0,0 @@
git-rename(1)
=============
NAME
----
git-rename - Script used to rename a file, directory or symlink.
SYNOPSIS
--------
'git-rename' <source> <destination>
DESCRIPTION
-----------
This script is used to rename a file, directory or symlink.
The index is updated after successful completion, but the change must still be
committed.
Author
------
Written by Linus Torvalds <torvalds@osdl.org>
Rewritten by Ryan Anderson <ryan@michonline.com>
Documentation
--------------
Documentation by David Greaves, Junio C Hamano and the git-list <git@vger.kernel.org>.
GIT
---
Part of the gitlink:git[7] suite

View File

@ -0,0 +1,170 @@
git-repo-config(1)
==================
NAME
----
git-repo-config - Get and set options in .git/config.
SYNOPSIS
--------
'git-repo-config' name [value [value_regex]]
'git-repo-config' --replace-all name [value [value_regex]]
'git-repo-config' --get name [value_regex]
'git-repo-config' --get-all name [value_regex]
'git-repo-config' --unset name [value_regex]
'git-repo-config' --unset-all name [value_regex]
DESCRIPTION
-----------
You can query/set/replace/unset options with this command. The name is
actually the section and the key separated by a dot, and the value will be
escaped.
If you want to set/unset an option which can occor on multiple lines, you
should provide a POSIX regex for the value. If you want to handle the lines
*not* matching the regex, just prepend a single exlamation mark in front
(see EXAMPLES).
This command will fail if
. .git/config is invalid,
. .git/config can not be written to,
. no section was provided,
. the section or key is invalid,
. you try to unset an option which does not exist, or
. you try to unset/set an option for which multiple lines match.
OPTIONS
-------
--replace-all::
Default behaviour is to replace at most one line. This replaces
all lines matching the key (and optionally the value_regex)
--get::
Get the value for a given key (optionally filtered by a regex
matching the value).
--get-all::
Like get, but does not fail if the number of values for the key
is not exactly one.
--unset::
Remove the line matching the key from .git/config.
--unset-all::
Remove all matching lines from .git/config.
EXAMPLE
-------
Given a .git/config like this:
#
# This is the config file, and
# a '#' or ';' character indicates
# a comment
#
; core variables
[core]
; Don't trust file modes
filemode = false
; Our diff algorithm
[diff]
external = "/usr/local/bin/gnu-diff -u"
renames = true
; Proxy settings
[proxy]
command="ssh" for "ssh://kernel.org/"
command="proxy-command" for kernel.org
command="myprotocol-command" for "my://"
command=default-proxy ; for all the rest
you can set the filemode to true with
------------
% git repo-config core.filemode true
------------
The hypothetic proxy command entries actually have a postfix to discern
to what URL they apply. Here is how to change the entry for kernel.org
to "ssh".
------------
% git repo-config proxy.command '"ssh" for kernel.org' 'for kernel.org$'
------------
This makes sure that only the key/value pair for kernel.org is replaced.
To delete the entry for renames, do
------------
% git repo-config --unset diff.renames
------------
If you want to delete an entry for a multivar (like proxy.command above),
you have to provide a regex matching the value of exactly one line.
To query the value for a given key, do
------------
% git repo-config --get core.filemode
------------
or
------------
% git repo-config core.filemode
------------
or, to query a multivar:
------------
% git repo-config --get proxy.command "for kernel.org$"
------------
If you want to know all the values for a multivar, do:
------------
% git repo-config --get-all proxy.command
------------
If you like to live dangerous, you can replace *all* proxy.commands by a
new one with
------------
% git repo-config --replace-all proxy.command ssh
------------
However, if you really only want to replace the line for the default proxy,
i.e. the one without a "for ..." postfix, do something like this:
------------
% git repo-config proxy.command ssh '! for '
------------
To actually match only values with an exclamation mark, you have to
------------
% git repo-config section.key value '[!]'
------------
Author
------
Written by Johannes Schindelin <Johannes.Schindelin@gmx.de>
Documentation
--------------
Documentation by Johannes Schindelin.
GIT
---
Part of the gitlink:git[7] suite

View File

@ -14,19 +14,30 @@ DESCRIPTION
Sets the current head to the specified commit and optionally resets the
index and working tree to match.
This command is useful if you notice some small error in a recent
commit (or set of commits) and want to redo that part without showing
the undo in the history.
If you want to undo a commit other than the latest on a branch,
gitlink:git-revert[1] is your friend.
OPTIONS
-------
--mixed::
Like --soft but reports what has not been updated. This is the
default action.
Resets the index but not the working tree (ie, the changed files
are preserved but not marked for commit) and reports what has not
been updated. This is the default action.
--soft::
Does not touch the index file nor the working tree at all, but
requires them in a good order.
requires them to be in a good order. This leaves all your changed
files "Updated but not checked in", as gitlink:git-status[1] would
put it.
--hard::
Matches the working tree and index to that of the tree being
switched to.
switched to. Any changes to tracked files in the working tree
since <commit-ish> are lost.
<commit-ish>::
Commit to make the current HEAD.

View File

@ -44,7 +44,7 @@ When importing incementally, you might need to edit the .git/svn2git file.
-i::
Import-only: don't perform a checkout after importing. This option
ensures the working directory and cache remain untouched and will
ensures the working directory and index remain untouched and will
not create them if they do not exist.
-t <trunk_subdir>::

View File

@ -24,8 +24,8 @@ Traditionally, `.git/HEAD` is a symlink pointing at
we did `ln -sf refs/heads/newbranch .git/HEAD`, and when we want
to find out which branch we are on, we did `readlink .git/HEAD`.
This was fine, and internally that is what still happens by
default, but on platforms that does not have working symlinks,
or that does not have the `readlink(1)` command, this was a bit
default, but on platforms that do not have working symlinks,
or that do not have the `readlink(1)` command, this was a bit
cumbersome. On some platforms, `ln -sf` does not even work as
advertised (horrors).

View File

@ -8,7 +8,7 @@ git-tag - Create a tag object signed with GPG
SYNOPSIS
--------
'git-tag' [-a | -s | -u <key-id>] [-f] [-m <msg>] <name> [<head>]
'git-tag' [-a | -s | -u <key-id>] [-f | -d] [-m <msg>] <name> [<head>]
DESCRIPTION
-----------
@ -30,6 +30,8 @@ A GnuPG signed tag object will be created when `-s` or `-u
committer identity for the current user is used to find the
GnuPG key for signing.
`-d <tag>` deletes the tag.
Author
------

View File

@ -8,7 +8,7 @@ git-unpack-objects - Unpack objects from a packed archive.
SYNOPSIS
--------
'git-unpack-objects' [-q] <pack-file
'git-unpack-objects' [-n] [-q] <pack-file
DESCRIPTION
@ -19,6 +19,10 @@ one-object" format in $GIT_OBJECT_DIRECTORY.
OPTIONS
-------
-n::
Only list the objects that would be unpacked, don't actually unpack
them.
-q::
The command usually shows percentage progress. This
flag suppresses it.

View File

@ -21,7 +21,7 @@ SYNOPSIS
DESCRIPTION
-----------
Modifies the index or directory cache. Each file mentioned is updated
into the cache and any 'unmerged' or 'needs updating' state is
into the index and any 'unmerged' or 'needs updating' state is
cleared.
The way "git-update-index" handles files it is told about can be modified
@ -30,26 +30,26 @@ using the various options:
OPTIONS
-------
--add::
If a specified file isn't in the cache already then it's
If a specified file isn't in the index already then it's
added.
Default behaviour is to ignore new files.
--remove::
If a specified file is in the cache but is missing then it's
If a specified file is in the index but is missing then it's
removed.
Default behaviour is to ignore removed file.
--refresh::
Looks at the current cache and checks to see if merges or
Looks at the current index and checks to see if merges or
updates are needed by checking stat() information.
-q::
Quiet. If --refresh finds that the cache needs an update, the
Quiet. If --refresh finds that the index needs an update, the
default behavior is to error out. This option makes
git-update-index continue anyway.
--unmerged::
If --refresh finds unmerged changes in the cache, the default
If --refresh finds unmerged changes in the index, the default
behavior is to error out. This option makes git-update-index
continue anyway.
@ -57,10 +57,10 @@ OPTIONS
Ignores missing files during a --refresh
--cacheinfo <mode> <object> <path>::
Directly insert the specified info into the cache.
Directly insert the specified info into the index.
--index-info::
Read index info from stdin.
Read index information from stdin.
--chmod=(+|-)x::
Set the execute permissions on the updated files.
@ -68,7 +68,7 @@ OPTIONS
--info-only::
Do not create objects in the object database for all
<file> arguments that follow this flag; just insert
their object IDs into the cache.
their object IDs into the index.
--force-remove::
Remove the file from the index even when the working directory
@ -106,14 +106,14 @@ OPTIONS
Using --refresh
---------------
'--refresh' does not calculate a new sha1 file or bring the cache
'--refresh' does not calculate a new sha1 file or bring the index
up-to-date for mode/content changes. But what it *does* do is to
"re-match" the stat information of a file with the cache, so that you
can refresh the cache for a file that hasn't been changed but where
"re-match" the stat information of a file with the index, so that you
can refresh the index for a file that hasn't been changed but where
the stat entry is out of date.
For example, you'd want to do this after doing a "git-read-tree", to link
up the stat cache details with the proper files.
up the stat index details with the proper files.
Using --cacheinfo or --info-only
--------------------------------

View File

@ -3,7 +3,7 @@ git-write-tree(1)
NAME
----
git-write-tree - Creates a tree object from the current cache
git-write-tree - Creates a tree object from the current index
SYNOPSIS
@ -12,11 +12,11 @@ SYNOPSIS
DESCRIPTION
-----------
Creates a tree object using the current cache.
Creates a tree object using the current index.
The cache must be merged.
The index must be merged.
Conceptually, "git-write-tree" sync()s the current directory cache contents
Conceptually, "git-write-tree" sync()s the current index contents
into a set of tree files.
In order to have that match what is actually in your directory right
now, you need to have done a "git-update-index" phase before you did the

View File

@ -8,13 +8,33 @@ git - the stupid content tracker
SYNOPSIS
--------
'git-<command>' <args>
'git' [--version] [--exec-path[=GIT_EXEC_PATH]] [--help] COMMAND [ARGS]
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
at the link:tutorial.html[tutorial] document.
@ -40,7 +60,7 @@ reflect recent changes.
Commands Overview
-----------------
The git commands can helpfully be split into those that manipulate
the repository, the cache and the working fileset, those that
the repository, the index and the working fileset, those that
interrogate and compare them, and those that moves objects and
references between repositories.
@ -59,7 +79,7 @@ gitlink:git-apply[1]::
applies it to the working tree.
gitlink:git-checkout-index[1]::
Copy files from the cache to the working directory
Copy files from the index to the working directory
gitlink:git-commit-tree[1]::
Creates a new commit object
@ -67,7 +87,7 @@ gitlink:git-commit-tree[1]::
gitlink:git-hash-object[1]::
Computes the object ID from a file.
gitlink:git-index-pack.html[1]::
gitlink:git-index-pack[1]::
Build pack index file for an existing packed archive.
gitlink:git-init-db[1]::
@ -86,7 +106,10 @@ gitlink:git-prune-packed[1]::
Remove extra objects that are already in pack files.
gitlink:git-read-tree[1]::
Reads tree information into the directory cache
Reads tree information into the directory index
gitlink:git-repo-config[1]::
Get and set options in .git/config.
gitlink:git-unpack-objects[1]::
Unpacks objects out of a packed archive.
@ -95,7 +118,7 @@ gitlink:git-update-index[1]::
Modifies the index or directory cache
gitlink:git-write-tree[1]::
Creates a tree from the current cache
Creates a tree from the current index
Interrogation commands
@ -105,10 +128,10 @@ gitlink:git-cat-file[1]::
Provide content or type information for repository objects
gitlink:git-diff-index[1]::
Compares content and mode of blobs between the cache and repository
Compares content and mode of blobs between the index and repository
gitlink:git-diff-files[1]::
Compares files in the working tree and the cache
Compares files in the working tree and the index
gitlink:git-diff-stages[1]::
Compares two "merge stages" in the index file.
@ -120,7 +143,7 @@ gitlink:git-fsck-objects[1]::
Verifies the connectivity and validity of the objects in the database
gitlink:git-ls-files[1]::
Information about files in the cache/working directory
Information about files in the index/working directory
gitlink:git-ls-tree[1]::
Displays a tree object in human readable form
@ -262,9 +285,6 @@ gitlink:git-push[1]::
gitlink:git-rebase[1]::
Rebase local commits to new upstream head.
gitlink:git-rename[1]::
Rename files and directories.
gitlink:git-repack[1]::
Pack unpacked objects in a repository.
@ -309,6 +329,9 @@ gitlink:git-convert-objects[1]::
gitlink:git-cvsimport[1]::
Salvage your data out of another SCM people love to hate.
gitlink:git-lost-found[1]::
Recover lost refs that luckily have not yet been pruned.
gitlink:git-merge-one-file[1]::
The standard helper program to use with "git-merge-index"
@ -490,8 +513,8 @@ git so take care if using Cogito etc
'GIT_INDEX_FILE'::
This environment allows the specification of an alternate
cache/index file. If not specified, the default of
`$GIT_DIR/index` is used.
index file. If not specified, the default of `$GIT_DIR/index`
is used.
'GIT_OBJECT_DIRECTORY'::
If the object storage directory is specified via this
@ -533,9 +556,12 @@ Discussion[[Discussion]]
------------------------
include::../README[]
Author
------
Written by Linus Torvalds <torvalds@osdl.org> and the git-list <git@vger.kernel.org>.
Authors
-------
git's founding father is Linus Torvalds <torvalds@osdl.org>.
The current git nurse is Junio C. Hamano <junkio@cox.net>.
The git potty was written by Andres Ericsson <ae@op5.se>.
General upbringing is handled by the git-list <git@vger.kernel.org>.
Documentation
--------------

View File

@ -43,14 +43,14 @@ DAG::
index::
A collection of files with stat information, whose contents are
stored as objects. The cache is a stored version of your working
stored as objects. The index is a stored version of your working
tree. Truth be told, it can also contain a second, and even a third
version of a working tree, which are used when merging.
index entry::
The information regarding a particular file, stored in the index.
An index entry can be unmerged, if a merge was started, but not
yet finished (i.e. if the cache contains multiple versions of
yet finished (i.e. if the index contains multiple versions of
that file).
unmerged index:
@ -75,7 +75,7 @@ checkout::
stored in the object database.
commit::
As a verb: The action of storing the current state of the cache in the
As a verb: The action of storing the current state of the index in the
object database. The result is a revision.
As a noun: Short hand for commit object.

View File

@ -0,0 +1,65 @@
From: Linus Torvalds <torvalds () osdl ! org>
To: git@vger.kernel.org
Date: 2005-11-08 1:31:34
Subject: Real-life kernel debugging scenario
Abstract: Short-n-sweet, Linus tells us how to leverage `git-bisect` to perform
bug isolation on a repository where "good" and "bad" revisions are known
in order to identify a suspect commit.
How To Use git-bisect To Isolate a Bogus Commit
===============================================
The way to use "git bisect" couldn't be easier.
Figure out what the oldest bad state you know about is (that's usually the
head of "master", since that's what you just tried to boot and failed at).
Also, figure out the most recent known-good commit (usually the _previous_
kernel you ran: and if you've only done a single "pull" in between, it
will be ORIG_HEAD).
Then do
git bisect start
git bisect bad master <- mark "master" as the bad state
git bisect good ORIG_HEAD <- mark ORIG_HEAD as good (or
whatever other known-good
thing you booted laste)
and at this point "git bisect" will churn for a while, and tell you what
the mid-point between those two commits are, and check that state out as
the head of the bew "bisect" branch.
Compile and reboot.
If it's good, just do
git bisect good <- mark current head as good
otherwise, reboot into a good kernel instead, and do (surprise surprise,
git really is very intuitive):
git bisect bad <- mark current head as bad
and whatever you do, git will select a new half-way point. Do this for a
while, until git tells you exactly which commit was the first bad commit.
That's your culprit.
It really works wonderfully well, except for the case where there was
_another_ commit that broke something in between, like introduced some
stupid compile error. In that case you should not mark that commit good or
bad: you should try to find another commit close-by, and do a "git reset
--hard <newcommit>" to try out _that_ commit instead, and then test that
instead (and mark it good or bad).
You can do "git bisect visualize" while you do all this to see what's
going on by starting up gitk on the bisection range.
Finally, once you've figured out exactly which commit was bad, you can
then go back to the master branch, and try reverting just that commit:
git checkout master
git revert <bad-commit-id>
to verify that the top-of-kernel works with that single commit reverted.

View File

@ -63,7 +63,7 @@ And then, you can just remove the broken branch if you decide you really
don't want it:
# remove 'broken' branch
rm .git/refs/heads/broken
git branch -d broken
# Prune old objects if you're really really sure
git prune

View File

@ -40,10 +40,7 @@ So I started from master, made a bunch of edits, and committed:
$ git checkout master
$ cd Documentation; ed git.txt ...
$ cd ..; git add Documentation/*.txt
$ git commit -s -v
NOTE. The -v flag to commit is a handy way to make sure that
your additions are not introducing bogusly formatted lines.
$ git commit -s
After the commit, the ancestry graph would look like this:
@ -98,7 +95,7 @@ to do cherrypicking using only the core GIT tools.
Let's go back to the earlier picture, with different labels.
You, as an individual developer, cloned upstream repository and
amde a couple of commits on top of it.
made a couple of commits on top of it.
*your "master" head
upstream --> #1 --> #2 --> #3

View File

@ -153,7 +153,8 @@ Everything is in the good order. I do not need the temporary branch
nor tag anymore, so remove them:
------------------------------------------------
$ rm -f .git/refs/tags/pu-anchor .git/refs/heads/revert-c99
$ rm -f .git/refs/tags/pu-anchor
$ git branch -d revert-c99
------------------------------------------------
It was an emergency fix, so we might as well merge it into the

View File

@ -0,0 +1,105 @@
From: Junio C Hamano <junkio@cox.net>
Subject: control access to branches.
Date: Thu, 17 Nov 2005 23:55:32 -0800
Message-ID: <7vfypumlu3.fsf@assigned-by-dhcp.cox.net>
Abstract: An example hooks/update script is presented to
implement repository maintenance policies, such as who can push
into which branch and who can make a tag.
When your developer runs git-push into the repository,
git-receive-pack is run (either locally or over ssh) as that
developer, so is hooks/update script. Quoting from the relevant
section of the documentation:
Before each ref is updated, if $GIT_DIR/hooks/update file exists
and executable, it is called with three parameters:
$GIT_DIR/hooks/update refname sha1-old sha1-new
The refname parameter is relative to $GIT_DIR; e.g. for the
master head this is "refs/heads/master". Two sha1 are the
object names for the refname before and after the update. Note
that the hook is called before the refname is updated, so either
sha1-old is 0{40} (meaning there is no such ref yet), or it
should match what is recorded in refname.
So if your policy is (1) always require fast-forward push
(i.e. never allow "git-push repo +branch:branch"), (2) you
have a list of users allowed to update each branch, and (3) you
do not let tags to be overwritten, then:
#!/bin/sh
# This is a sample hooks/update script, written by JC
# in his e-mail buffer, so naturally it is not tested
# but hopefully would convey the idea.
umask 002
case "$1" in
refs/tags/*)
# No overwriting an existing tag
if test -f "$GIT_DIR/$1"
then
exit 1
fi
;;
refs/heads/*)
# No rebasing or rewinding
if expr "$2" : '0*$' >/dev/null
then
# creating a new branch
;
else
# updating -- make sure it is a fast forward
mb=`git-merge-base "$2" "$3"`
case "$mb,$2" in
"$2,$mb")
;; # fast forward -- happy
*)
exit 1 ;; # unhappy
esac
fi
;;
*)
# No funny refs allowed
exit 1
;;
esac
# Is the user allowed to update it?
me=`id -u -n` ;# e.g. "junio"
while read head_pattern users
do
if expr "$1" : "$head_pattern" >/dev/null
then
case " $users " in
*" $me "*)
exit 0 ;; # happy
' * ')
exit 0 ;; # anybody
esac
fi
done
exit 1
For the sake of simplicity, I assumed that you keep something
like this in $GIT_DIR/info/allowed-pushers file:
refs/heads/master junio
refs/heads/cogito$ pasky
refs/heads/bw/ linus
refs/heads/tmp/ *
refs/tags/v[0-9]* junio
With this, Linus can push or create "bw/penguin" or "bw/zebra"
or "bw/panda" branches, Pasky can do only "cogito", and I can do
master branch and make versioned tags. And anybody can do
tmp/blah branches. This assumes all the users are in a single
group that can write into $GIT_DIR/ and underneath.

View File

@ -9,7 +9,7 @@ GIT as a Linux subsystem maintainer.
-Tony
Last updated w.r.t. GIT 0.99.5
Last updated w.r.t. GIT 0.99.9f
Linux subsystem maintenance using GIT
-------------------------------------
@ -89,8 +89,8 @@ out at the current tip of the linus branch.
These can be easily kept up to date by merging from the "linus" branch:
$ git checkout test && git resolve test linus "Auto-update from upstream"
$ git checkout release && git resolve release linus "Auto-update from upstream"
$ git checkout test && git merge "Auto-update from upstream" test linus
$ git checkout release && git merge "Auto-update from upstream" release linus
Set up so that you can push upstream to your public tree (you need to
log-in to the remote system and create an empty tree there before the
@ -128,7 +128,7 @@ commit to this branch.
When you are happy with the state of this change, you can pull it into the
"test" branch in preparation to make it public:
$ git checkout test && git resolve test speed-up-spinlocks "Pull speed-up-spinlock changes"
$ git checkout test && git merge "Pull speed-up-spinlock changes" test speed-up-spinlocks
It is unlikely that you would have any conflicts here ... but you might if you
spent a while on this step and had also pulled new versions from upstream.
@ -138,7 +138,7 @@ same branch into the "release" tree ready to go upstream. This is where you
see the value of keeping each patch (or patch series) in its own branch. It
means that the patches can be moved into the "release" tree in any order.
$ git checkout release && git resolve release speed-up-spinlocks "Pull speed-up-spinlock changes"
$ git checkout release && git merge "Pull speed-up-spinlock changes" release speed-up-spinlocks
After a while, you will have a number of branches, and despite the
well chosen names you picked for each of them, you may forget what
@ -166,7 +166,7 @@ output from:
is empty. At this point the branch can be deleted:
$ rm .git/refs/heads/branchname
$ git branch -d branchname
Some changes are so trivial that it is not necessary to create a separate
branch and then merge into each of the test and release branches. For
@ -190,7 +190,7 @@ Here are some of the scripts that I use to simplify all this even further.
case "$1" in
test|release)
git checkout $1 && git resolve $1 linus "Auto-update from upstream"
git checkout $1 && git merge "Auto-update from upstream" $1 linus
;;
linus)
before=$(cat .git/refs/heads/linus)
@ -231,7 +231,7 @@ test|release)
echo $1 already merged into $2 1>&2
exit 1
fi
git checkout $2 && git resolve $2 $1 "Pull $1 into $2 branch"
git checkout $2 && git merge "Pull $1 into $2 branch" $2 $1
;;
*)
usage

View File

@ -2,7 +2,7 @@
T="$1"
for h in *.html howto/*.txt howto/*.html
for h in *.html *.txt howto/*.txt howto/*.html
do
diff -u -I'Last updated [0-9][0-9]-[A-Z][a-z][a-z]-' "$T/$h" "$h" || {
echo >&2 "# install $h $T/$h"
@ -12,7 +12,7 @@ do
}
done
strip_leading=`echo "$T/" | sed -e 's|.|.|g'`
for th in "$T"/*.html "$T"/howto/*.txt "$T"/howto/*.html
for th in "$T"/*.html "$T"/*.txt "$T"/howto/*.txt "$T"/howto/*.html
do
h=`expr "$th" : "$strip_leading"'\(.*\)'`
case "$h" in

View File

@ -0,0 +1,16 @@
-n, \--no-summary::
Do not show diffstat at the end of the merge.
--no-commit::
Perform the merge but pretend the merge failed and do
not autocommit, to give the user a chance to inspect and
further tweak the merge result before committing.
-s <strategy>, \--strategy=<strategy>::
Use the given merge strategy; can be supplied more than
once to specify them in the order they should be tried.
If there is no `-s` option, a built-in list of strategies
is used instead (`git-merge-resolve` when merging a single
head, `git-merge-octopus` otherwise).

View File

@ -1,14 +0,0 @@
-n, --no-summary::
Do not show diffstat at the end of the merge.
--no-commit::
Perform the merge but pretend the merge failed and do
not autocommit, to give the user a chance to inspect and
further tweak the merge result before committing.
-s <strategy>::
use that merge strategy; can be given more than once to
specify them in the order they should be tried. If
there is no `-s` option, built-in list of strategies is
used instead (`git-merge-resolve` when merging a single
head, `git-merge-octopus` otherwise).

View File

@ -0,0 +1,35 @@
MERGE STRATEGIES
----------------
resolve::
This can only resolve two heads (i.e. the current branch
and another branch you pulled from) using 3-way merge
algorithm. It tries to carefully detect criss-cross
merge ambiguities and is considered generally safe and
fast. This is the default merge strategy when pulling
one branch.
recursive::
This can only resolve two heads using 3-way merge
algorithm. When there are more than one common
ancestors that can be used for 3-way merge, it creates a
merged tree of the common ancestores and uses that as
the reference tree for the 3-way merge. This has been
reported to result in fewer merge conflicts without
causing mis-merges by tests done on actual merge commits
taken from Linux 2.6 kernel development history.
Additionally this can detect and handle merges involving
renames.
octopus::
This resolves more than two-head case, but refuses to do
complex merge that needs manual resolution. It is
primarily meant to be used for bundling topic branch
heads together. This is the default merge strategy when
pulling more than one branch.
ours::
This resolves any number of heads, but the result of the
merge is always the current branch head. It is meant to
be used to supersede old development history of side
branches.

View File

@ -5,11 +5,31 @@
to name the remote repository:
+
===============================================================
- Rsync URL: rsync://remote.machine/path/to/repo.git/
- HTTP(s) URL: http://remote.machine/path/to/repo.git/
- git URL: git://remote.machine/path/to/repo.git/
or remote.machine:/path/to/repo.git/
- Local directory: /path/to/repo.git/
- rsync://host.xz/path/to/repo.git/
- http://host.xz/path/to/repo.git/
- https://host.xz/path/to/repo.git/
- git://host.xz/path/to/repo.git/
- git://host.xz/~user/path/to/repo.git/
- ssh://host.xz/path/to/repo.git/
- ssh://host.xz/~user/path/to/repo.git/
- ssh://host.xz/~/path/to/repo.git
===============================================================
+
SSH Is the default transport protocol and also supports an
scp-like syntax. Both syntaxes support username expansion,
as does the native git protocol. The following three are
identical to the last three above, respectively:
+
===============================================================
- host.xz:/path/to/repo.git/
- host.xz:~user/path/to/repo.git/
- host.xz:path/to/repo.git
===============================================================
+
To sync with a local directory, use:
===============================================================
- /path/to/repo.git/
===============================================================
+
In addition to the above, as a short-hand, the name of a
@ -82,14 +102,19 @@ must know this is the expected usage pattern for a branch.
[NOTE]
You never do your own development on branches that appear
on the right hand side of a <refspec> colon on `Pull:` lines;
they are to be updated by `git-fetch`. The corollary is that
a local branch should be introduced and named on a <refspec>
right-hand-side if you intend to do development derived from
that branch.
This leads to the common `Pull: master:origin` mapping of a
remote `master` branch to a local `origin` branch, which
is then merged to a local development branch, again typically
named `master`.
they are to be updated by `git-fetch`. If you intend to do
development derived from a remote branch `B`, have a `Pull:`
line to track it (i.e. `Pull: B:remote-B`), and have a separate
branch `my-B` to do your development on top of it. The latter
is created by `git branch my-B remote-B` (or its equivalent `git
checkout -b my-B remote-B`). Run `git fetch` to keep track of
the progress of the remote side, and when you see something new
on the remote branch, merge it into your development branch with
`git pull . remote-B`, while you are on `my-B` branch.
The common `Pull: master:origin` mapping of a remote `master`
branch to a local `origin` branch, which is then merged to a
ocal development branch, again typically named `master`, is made
when you run `git clone` for you to follow this pattern.
+
[NOTE]
There is a difference between listing multiple <refspec>

View File

@ -36,14 +36,16 @@ To start up, create a subdirectory for it, change into that
subdirectory, and initialize the git infrastructure with `git-init-db`:
------------------------------------------------
mkdir git-tutorial
cd git-tutorial
git-init-db
$ mkdir git-tutorial
$ cd git-tutorial
$ git-init-db
------------------------------------------------
to which git will reply
defaulting to local storage area
----------------
defaulting to local storage area
----------------
which is just git's way of saying that you haven't been doing anything
strange, and that it will have created a local `.git` directory setup for
@ -114,8 +116,8 @@ in your git repository. We'll start off with a few bad examples, just to
get a feel for how this works:
------------------------------------------------
echo "Hello World" >hello
echo "Silly example" >example
$ echo "Hello World" >hello
$ echo "Silly example" >example
------------------------------------------------
you have now created two files in your working tree (aka 'working directory'), but to
@ -129,7 +131,7 @@ actually check in your hard work, you will have to go through two steps:
The first step is trivial: when you want to tell git about any changes
to your working tree, you use the `git-update-index` program. That
program normally just takes a list of filenames you want to update, but
to avoid trivial mistakes, it refuses to add new entries to the cache
to avoid trivial mistakes, it refuses to add new entries to the index
(or remove existing ones) unless you explicitly tell it that you're
adding a new entry with the `\--add` flag (or removing an entry with the
`\--remove`) flag.
@ -137,7 +139,7 @@ adding a new entry with the `\--add` flag (or removing an entry with the
So to populate the index with the two files you just created, you can do
------------------------------------------------
git-update-index --add hello example
$ git-update-index --add hello example
------------------------------------------------
and you have now told git to track those two files.
@ -146,12 +148,17 @@ In fact, as you did that, if you now look into your object directory,
you'll notice that git will have added two new objects to the object
database. If you did exactly the steps above, you should now be able to do
ls .git/objects/??/*
----------------
$ ls .git/objects/??/*
----------------
and see two files:
.git/objects/55/7db03de997c86a4a028e1ebd3a1ceb225be238
.git/objects/f2/4c74a2e500f5ee1332c86b94199f52b1d1d962
----------------
.git/objects/55/7db03de997c86a4a028e1ebd3a1ceb225be238
.git/objects/f2/4c74a2e500f5ee1332c86b94199f52b1d1d962
----------------
which correspond with the objects with names of 557db... and f24c7..
respectively.
@ -159,13 +166,17 @@ respectively.
If you want to, you can use `git-cat-file` to look at those objects, but
you'll have to use the object name, not the filename of the object:
git-cat-file -t 557db03de997c86a4a028e1ebd3a1ceb225be238
----------------
$ git-cat-file -t 557db03de997c86a4a028e1ebd3a1ceb225be238
----------------
where the `-t` tells `git-cat-file` to tell you what the "type" of the
object is. git will tell you that you have a "blob" object (ie just a
regular file), and you can see the contents with
git-cat-file "blob" 557db03
----------------
$ git-cat-file "blob" 557db03
----------------
which will print out "Hello World". The object 557db03 is nothing
more than the contents of your file `hello`.
@ -188,7 +199,7 @@ was just to show that `git-update-index` did something magical, and
actually saved away the contents of your files into the git object
database.
Updating the cache did something else too: it created a `.git/index`
Updating the index did something else too: it created a `.git/index`
file. This is the index that describes your current working tree, and
something you should be very aware of. Again, you normally never worry
about the index file itself, but you should be aware of the fact that
@ -202,7 +213,7 @@ In particular, let's not even check in the two files into git yet, we'll
start off by adding another line to `hello` first:
------------------------------------------------
echo "It's a new day for git" >>hello
$ echo "It's a new day for git" >>hello
------------------------------------------------
and you can now, since you told git about the previous state of `hello`, ask
@ -210,7 +221,7 @@ git what has changed in the tree compared to your old index, using the
`git-diff-files` command:
------------
git-diff-files
$ git-diff-files
------------
Oops. That wasn't very readable. It just spit out its own internal
@ -222,12 +233,7 @@ To make it readable, we can tell git-diff-files to output the
differences as a patch, using the `-p` flag:
------------
git-diff-files -p
------------
which will spit out
------------
$ git-diff-files -p
diff --git a/hello b/hello
index 557db03..263414f 100644
--- a/hello
@ -264,13 +270,15 @@ filenames with their contents (and their permissions), and we're
creating the equivalent of a git "directory" object:
------------------------------------------------
git-write-tree
$ git-write-tree
------------------------------------------------
and this will just output the name of the resulting tree, in this case
(if you have done exactly as I've described) it should be
8988da15d077d4829fc51d8544c097def6644dbb
----------------
8988da15d077d4829fc51d8544c097def6644dbb
----------------
which is another incomprehensible object name. Again, if you want to,
you can use `git-cat-file -t 8988d\...` to see that this time the object
@ -299,14 +307,16 @@ that's exactly what `git-commit-tree` spits out, we can do this
all with a sequence of simple shell commands:
------------------------------------------------
tree=$(git-write-tree)
commit=$(echo 'Initial commit' | git-commit-tree $tree)
git-update-ref HEAD $(commit)
$ tree=$(git-write-tree)
$ commit=$(echo 'Initial commit' | git-commit-tree $tree)
$ git-update-ref HEAD $commit
------------------------------------------------
which will say:
Committing initial tree 8988da15d077d4829fc51d8544c097def6644dbb
----------------
Committing initial tree 8988da15d077d4829fc51d8544c097def6644dbb
----------------
just to warn you about the fact that it created a totally new commit
that is not related to anything else. Normally you do this only *once*
@ -349,7 +359,9 @@ didn't have anything to diff against.
But now we can do
git-diff-index -p HEAD
----------------
$ git-diff-index -p HEAD
----------------
(where `-p` has the same meaning as it did in `git-diff-files`), and it
will show us the same difference, but for a totally different reason.
@ -360,7 +372,9 @@ are obviously the same, so we get the same result.
Again, because this is a common operation, you can also just shorthand
it with
git diff HEAD
----------------
$ git diff HEAD
----------------
which ends up doing the above for you.
@ -396,7 +410,7 @@ work through the index file, so the first thing we need to do is to
update the index cache:
------------------------------------------------
git-update-index hello
$ git-update-index hello
------------------------------------------------
(note how we didn't need the `\--add` flag this time, since git knew
@ -417,7 +431,7 @@ this wasn't an initial commit any more), but you've done that once
already, so let's just use the helpful script this time:
------------------------------------------------
git commit
$ git commit
------------------------------------------------
which starts an editor for you to write the commit message and tells you
@ -426,7 +440,7 @@ a bit about what you have done.
Write whatever message you want, and all the lines that start with '#'
will be pruned out, and the rest will be used as the commit message for
the change. If you decide you don't want to commit anything after all at
this point (you can continue to edit things and update the cache), you
this point (you can continue to edit things and update the index), you
can just leave an empty message. Otherwise `git commit` will commit
the change for you.
@ -450,7 +464,9 @@ give it just a single commit object, and it will figure out the parent
of that commit itself, and show the difference directly. Thus, to get
the same diff that we've already seen several times, we can now do
git-diff-tree -p HEAD
----------------
$ git-diff-tree -p HEAD
----------------
(again, `-p` means to show the difference as a human-readable patch),
and it will show what the last commit (in `HEAD`) actually changed.
@ -505,13 +521,17 @@ activities.
To see the whole history of our pitiful little git-tutorial project, you
can do
git log
----------------
$ git log
----------------
which shows just the log messages, or if we want to see the log together
with the associated patches use the more complex (and much more
powerful)
git-whatchanged -p --root
----------------
$ git-whatchanged -p --root
----------------
and you will see exactly what has changed in the repository over its
short history.
@ -547,14 +567,16 @@ it in the `.git/refs/tags/` subdirectory instead of calling it a `head`.
So the simplest form of tag involves nothing more than
------------------------------------------------
git tag my-first-tag
$ git tag my-first-tag
------------------------------------------------
which just writes the current `HEAD` into the `.git/refs/tags/my-first-tag`
file, after which point you can then use this symbolic name for that
particular state. You can, for example, do
git diff my-first-tag
----------------
$ git diff my-first-tag
----------------
to diff your current state against that tag (which at this point will
obviously be an empty diff, but if you continue to develop and commit
@ -568,7 +590,9 @@ you really did
that tag. You create these annotated tags with either the `-a` or
`-s` flag to `git tag`:
git tag -s <tagname>
----------------
$ git tag -s <tagname>
----------------
which will sign the current `HEAD` (but you can also give it another
argument that specifies the thing to tag, ie you could have tagged the
@ -584,8 +608,8 @@ name for the state at that point.
Copying repositories
--------------------
git repositories are normally totally self-sufficient, and it's worth noting
that unlike CVS, for example, there is no separate notion of
git repositories are normally totally self-sufficient and relocatable
Unlike CVS, for example, there is no separate notion of
"repository" and "working tree". A git repository normally *is* the
working tree, with the local git information hidden in the `.git`
subdirectory. There is nothing else. What you see is what you got.
@ -602,8 +626,10 @@ This has two implications:
- if you grow bored with the tutorial repository you created (or you've
made a mistake and want to start all over), you can just do simple
rm -rf git-tutorial
+
----------------
$ rm -rf git-tutorial
----------------
+
and it will be gone. There's no external repository, and there's no
history outside the project you created.
@ -618,8 +644,10 @@ Note that when you've moved or copied a git repository, your git index
file (which caches various information, notably some of the "stat"
information for the files involved) will likely need to be refreshed.
So after you do a `cp -a` to create a new copy, you'll want to do
git-update-index --refresh
+
----------------
$ git-update-index --refresh
----------------
+
in the new repository to make sure that the index file is up-to-date.
@ -633,8 +661,10 @@ repositories you often want to make sure that the index cache is in some
known state (you don't know *what* they've done and not yet checked in),
so usually you'll precede the `git-update-index` with a
git-read-tree --reset HEAD
git-update-index --refresh
----------------
$ git-read-tree --reset HEAD
$ git-update-index --refresh
----------------
which will force a total index re-build from the tree pointed to by `HEAD`.
It resets the index contents to `HEAD`, and then the `git-update-index`
@ -645,7 +675,9 @@ tells you they need to be updated.
The above can also be written as simply
git reset
----------------
$ git reset
----------------
and in fact a lot of the common git command combinations can be scripted
with the `git xyz` interfaces. You can learn things by just looking
@ -665,20 +697,26 @@ first create your own subdirectory for the project, and then copy the
raw repository contents into the `.git` directory. For example, to
create your own copy of the git repository, you'd do the following
mkdir my-git
cd my-git
rsync -rL rsync://rsync.kernel.org/pub/scm/git/git.git/ .git
----------------
$ mkdir my-git
$ cd my-git
$ rsync -rL rsync://rsync.kernel.org/pub/scm/git/git.git/ .git
----------------
followed by
git-read-tree HEAD
----------------
$ git-read-tree HEAD
----------------
to populate the index. However, now you have populated the index, and
you have all the git internal files, but you will notice that you don't
actually have any of the working tree files to work on. To get
those, you'd check them out with
git-checkout-index -u -a
----------------
$ git-checkout-index -u -a
----------------
where the `-u` flag means that you want the checkout to keep the index
up-to-date (so that you don't have to refresh it afterward), and the
@ -689,9 +727,11 @@ files).
Again, this can all be simplified with
git clone rsync://rsync.kernel.org/pub/scm/git/git.git/ my-git
cd my-git
git checkout
----------------
$ git clone rsync://rsync.kernel.org/pub/scm/git/git.git/ my-git
$ cd my-git
$ git checkout
----------------
which will end up doing all of the above for you.
@ -719,7 +759,7 @@ used earlier, and create a branch in it. You do that by simply just
saying that you want to check out a new branch:
------------
git checkout -b mybranch
$ git checkout -b mybranch
------------
will create a new branch based at the current `HEAD` position, and switch
@ -733,7 +773,7 @@ just telling `git checkout` what the base of the checkout would be.
In other words, if you have an earlier tag or branch, you'd just do
------------
git checkout -b mybranch earlier-commit
$ git checkout -b mybranch earlier-commit
------------
and it would create the new branch `mybranch` at the earlier commit,
@ -743,27 +783,27 @@ and check out the state at that time.
You can always just jump back to your original `master` branch by doing
------------
git checkout master
$ git checkout master
------------
(or any other branch-name, for that matter) and if you forget which
branch you happen to be on, a simple
------------
ls -l .git/HEAD
$ ls -l .git/HEAD
------------
will tell you where it's pointing (Note that on platforms with bad or no
symlink support, you have to execute
------------
cat .git/HEAD
$ cat .git/HEAD
------------
instead). To get the list of branches you have, you can say
------------
git branch
$ git branch
------------
which is nothing more than a simple script around `ls .git/refs/heads`.
@ -773,7 +813,7 @@ Sometimes you may wish to create a new branch _without_ actually
checking it out and switching to it. If so, just use the command
------------
git branch <branchname> [startingpoint]
$ git branch <branchname> [startingpoint]
------------
which will simply _create_ the branch, but will not do anything further.
@ -792,9 +832,9 @@ being the same as the original `master` branch, let's make sure we're in
that branch, and do some work there.
------------------------------------------------
git checkout mybranch
echo "Work, work, work" >>hello
git commit -m 'Some work.' hello
$ git checkout mybranch
$ echo "Work, work, work" >>hello
$ git commit -m 'Some work.' hello
------------------------------------------------
Here, we just added another line to `hello`, and we used a shorthand for
@ -807,7 +847,7 @@ does some work in the original branch, and simulate that by going back
to the master branch, and editing the same file differently there:
------------
git checkout master
$ git checkout master
------------
Here, take a moment to look at the contents of `hello`, and notice how they
@ -815,9 +855,9 @@ don't contain the work we just did in `mybranch` -- because that work
hasn't happened in the `master` branch at all. Then do
------------
echo "Play, play, play" >>hello
echo "Lots of fun" >>example
git commit -m 'Some fun.' hello example
$ echo "Play, play, play" >>hello
$ echo "Lots of fun" >>example
$ git commit -m 'Some fun.' hello example
------------
since the master branch is obviously in a much better mood.
@ -826,7 +866,9 @@ Now, you've got two branches, and you decide that you want to merge the
work done. Before we do that, let's introduce a cool graphical tool that
helps you view what's going on:
gitk --all
----------------
$ gitk --all
----------------
will show you graphically both of your branches (that's what the `\--all`
means: normally it will just show you your current `HEAD`) and their
@ -836,14 +878,14 @@ source.
Anyway, let's exit `gitk` (`^Q` or the File menu), and decide that we want
to merge the work we did on the `mybranch` branch into the `master`
branch (which is currently our `HEAD` too). To do that, there's a nice
script called `git resolve`, which wants to know which branches you want
script called `git merge`, which wants to know which branches you want
to resolve and what the merge is all about:
------------
git resolve HEAD mybranch "Merge work in mybranch"
$ git merge "Merge work in mybranch" HEAD mybranch
------------
where the third argument is going to be used as the commit message if
where the first argument is going to be used as the commit message if
the merge can be resolved automatically.
Now, in this case we've intentionally created a situation where the
@ -851,12 +893,16 @@ merge will need to be fixed up by hand, though, so git will do as much
of it as it can automatically (which in this case is just merge the `example`
file, which had no differences in the `mybranch` branch), and say:
Simple merge failed, trying Automatic merge
Auto-merging hello.
----------------
Trying really trivial in-index merge...
fatal: Merge requires file-level merging
Nope.
...
merge: warning: conflicts during merge
ERROR: Merge conflict in hello.
fatal: merge program failed
Automatic merge failed, fix up by hand
Automatic merge failed/prevented; fix up by hand
----------------
which is way too verbose, but it basically tells you that it failed the
really trivial merge ("Simple merge") and did an "Automatic merge"
@ -877,7 +923,7 @@ Work, work, work
and once you're happy with your manual merge, just do a
------------
git commit hello
$ git commit hello
------------
which will very loudly warn you that you're now committing a merge
@ -927,17 +973,19 @@ to the `master` branch. Let's go back to `mybranch`, and run
resolve to get the "upstream changes" back to your branch.
------------
git checkout mybranch
git resolve HEAD master "Merge upstream changes."
$ git checkout mybranch
$ git merge "Merge upstream changes." HEAD master
------------
This outputs something like this (the actual commit object names
would be different)
Updating from ae3a2da... to a80b4aa....
example | 1 +
hello | 1 +
2 files changed, 2 insertions(+), 0 deletions(-)
----------------
Updating from ae3a2da... to a80b4aa....
example | 1 +
hello | 1 +
2 files changed, 2 insertions(+), 0 deletions(-)
----------------
Because your branch did not contain anything more than what are
already merged into the `master` branch, the resolve operation did
@ -963,14 +1011,16 @@ Merging external work
It's usually much more common that you merge with somebody else than
merging with your own branches, so it's worth pointing out that git
makes that very easy too, and in fact, it's not that different from
doing a `git resolve`. In fact, a remote merge ends up being nothing
doing a `git merge`. In fact, a remote merge ends up being nothing
more than "fetch the work from a remote repository into a temporary tag"
followed by a `git resolve`.
followed by a `git merge`.
Fetching from a remote repository is done by, unsurprisingly,
`git fetch`:
git fetch <remote-repository>
----------------
$ git fetch <remote-repository>
----------------
One of the following transports can be used to name the
repository to download from:
@ -1015,7 +1065,7 @@ This transport was designed for anonymous downloading. Like SSH
transport, it finds out the set of objects the downstream side
lacks and transfers (close to) minimum set of objects.
HTTP(s)::
HTTP(S)::
`http://remote.machine/path/to/repo.git/`
+
HTTP and HTTPS transport are used only for downloading. They
@ -1045,7 +1095,9 @@ However -- it's such a common thing to `fetch` and then
immediately `resolve`, that it's called `git pull`, and you can
simply do
git pull <remote-repository>
----------------
$ git pull <remote-repository>
----------------
and optionally give a branch-name for the remote end as a second
argument.
@ -1073,8 +1125,8 @@ the remote repository URL in a file under .git/remotes/
directory, like this:
------------------------------------------------
mkdir -p .git/remotes/
cat >.git/remotes/linus <<\EOF
$ mkdir -p .git/remotes/
$ cat >.git/remotes/linus <<\EOF
URL: http://www.kernel.org/pub/scm/git/git.git/
EOF
------------------------------------------------
@ -1084,7 +1136,7 @@ The URL specified in such file can even be a prefix
of a full URL, like this:
------------------------------------------------
cat >.git/remotes/jgarzik <<\EOF
$ cat >.git/remotes/jgarzik <<\EOF
URL: http://www.kernel.org/pub/scm/linux/git/jgarzik/
EOF
------------------------------------------------
@ -1103,6 +1155,156 @@ the above are equivalent to:
. `git pull http://www.kernel.org/pub/.../jgarzik/netdev-2.6.git e100`
How does the merge work?
------------------------
We said this tutorial shows what plumbing does to help you cope
with the porcelain that isn't flushing, but we so far did not
talk about how the merge really works. If you are following
this tutorial the first time, I'd suggest to skip to "Publishing
your work" section and come back here later.
OK, still with me? To give us an example to look at, let's go
back to the earlier repository with "hello" and "example" file,
and bring ourselves back to the pre-merge state:
------------
$ git show-branch --more=3 master mybranch
! [master] Merge work in mybranch
* [mybranch] Merge work in mybranch
--
++ [master] Merge work in mybranch
++ [master^2] Some work.
++ [master^] Some fun.
------------
Remember, before running `git merge`, our `master` head was at
"Some fun." commit, while our `mybranch` head was at "Some
work." commit.
------------
$ git checkout mybranch
$ git reset --hard master^2
$ git checkout master
$ git reset --hard master^
------------
After rewinding, the commit structure should look like this:
------------
$ git show-branch
* [master] Some fun.
! [mybranch] Some work.
--
+ [mybranch] Some work.
+ [master] Some fun.
++ [mybranch^] New day.
------------
Now we are ready to experiment with the merge by hand.
`git merge` command, when merging two branches, uses 3-way merge
algorithm. First, it finds the common ancestor between them.
The command it uses is `git-merge-base`:
------------
$ mb=$(git-merge-base HEAD mybranch)
------------
The command writes the commit object name of the common ancestor
to the standard output, so we captured its output to a variable,
because we will be using it in the next step. BTW, the common
ancestor commit is the "New day." commit in this case. You can
tell it by:
------------
$ git-name-rev $mb
my-first-tag
------------
After finding out a common ancestor commit, the second step is
this:
------------
$ git-read-tree -m -u $mb HEAD mybranch
------------
This is the same `git-read-tree` command we have already seen,
but it takes three trees, unlike previous examples. This reads
the contents of each tree into different 'stage' in the index
file (the first tree goes to stage 1, the second stage 2,
etc.). After reading three trees into three stages, the paths
that are the same in all three stages are 'collapsed' into stage
0. Also paths that are the same in two of three stages are
collapsed into stage 0, taking the SHA1 from either stage 2 or
stage 3, whichever is different from stage 1 (i.e. only one side
changed from the common ancestor).
After 'collapsing' operation, paths that are different in three
trees are left in non-zero stages. At this point, you can
inspect the index file with this command:
------------
$ git-ls-files --stage
100644 7f8b141b65fdcee47321e399a2598a235a032422 0 example
100644 263414f423d0e4d70dae8fe53fa34614ff3e2860 1 hello
100644 06fa6a24256dc7e560efa5687fa84b51f0263c3a 2 hello
100644 cc44c73eb783565da5831b4d820c962954019b69 3 hello
------------
In our example of only two files, we did not have unchanged
files so only 'example' resulted in collapsing, but in real-life
large projects, only small number of files change in one commit,
and this 'collapsing' tends to trivially merge most of the paths
fairly quickly, leaving only a handful the real changes in non-zero
stages.
To look at only non-zero stages, use `\--unmerged` flag:
------------
$ git-ls-files --unmerged
100644 263414f423d0e4d70dae8fe53fa34614ff3e2860 1 hello
100644 06fa6a24256dc7e560efa5687fa84b51f0263c3a 2 hello
100644 cc44c73eb783565da5831b4d820c962954019b69 3 hello
------------
The next step of merging is to merge these three versions of the
file, using 3-way merge. This is done by giving
`git-merge-one-file` command as one of the arguments to
`git-merge-index` command:
------------
$ git-merge-index git-merge-one-file hello
Auto-merging hello.
merge: warning: conflicts during merge
ERROR: Merge conflict in hello.
fatal: merge program failed
------------
`git-merge-one-file` script is called with parameters to
describe those three versions, and is responsible to leave the
merge results in the working tree and register it in the index
file. It is a fairly straightforward shell script, and
eventually calls `merge` program from RCS suite to perform the
file-level 3-way merge. In this case, `merge` detects
conflicts, and the merge result with conflict marks is left in
the working tree, while the index file is updated with the
version from the current branch (this is to make `git diff`
useful after this step). This can be seen if you run `ls-files
--stage` again at this point:
------------
$ git-ls-files --stage
100644 7f8b141b65fdcee47321e399a2598a235a032422 0 example
100644 06fa6a24256dc7e560efa5687fa84b51f0263c3a 0 hello
------------
As you can see, there is no unmerged paths in the index file.
This is the state of the index file and the working file after
`git merge` returns control back to you, leaving the conflicting
merge for you to resolve.
Publishing your work
--------------------
@ -1148,7 +1350,7 @@ project `my-git`. After logging into the remote machine, create
an empty directory:
------------
mkdir my-git.git
$ mkdir my-git.git
------------
Then, make that directory into a git repository by running
@ -1156,7 +1358,7 @@ Then, make that directory into a git repository by running
`.git`, we do things slightly differently:
------------
GIT_DIR=my-git.git git-init-db
$ GIT_DIR=my-git.git git-init-db
------------
Make sure this directory is available for others you want your
@ -1182,7 +1384,7 @@ Come back to the machine you have your private repository. From
there, run this command:
------------
git push <public-host>:/path/to/my-git.git master
$ git push <public-host>:/path/to/my-git.git master
------------
This synchronizes your public repository to match the named
@ -1194,7 +1396,7 @@ repository. Kernel.org mirror network takes care of the
propagation to other publicly visible machines:
------------
git push master.kernel.org:/pub/scm/git/git.git/
$ git push master.kernel.org:/pub/scm/git/git.git/
------------
@ -1209,7 +1411,7 @@ immutable once they are created, there is a way to optimize the
storage by "packing them together". The command
------------
git repack
$ git repack
------------
will do it for you. If you followed the tutorial examples, you
@ -1235,7 +1437,7 @@ Once you have packed objects, you do not need to leave the
unpacked objects that are contained in the pack file anymore.
------------
git prune-packed
$ git prune-packed
------------
would remove them for you.
@ -1332,7 +1534,10 @@ on that project and has an own "public repository" goes like this:
the "project lead" person does.
3. Copy over the packed files from "project lead" public
repository to your public repository.
repository to your public repository, unless the "project
lead" repository lives on the same machine as yours. In the
latter case, you can use `objects/info/alternates` file to
point at the repository you are borrowing from.
4. Push into the public repository from your primary
repository. Run `git repack`, and possibly `git prune` if the
@ -1464,8 +1669,8 @@ in both of them. You could merge in 'diff-fix' first and then
'commit-fix' next, like this:
------------
$ git resolve master diff-fix 'Merge fix in diff-fix'
$ git resolve master commit-fix 'Merge fix in commit-fix'
$ git merge 'Merge fix in diff-fix' master diff-fix
$ git merge 'Merge fix in commit-fix' master commit-fix
------------
Which would result in:
@ -1498,8 +1703,8 @@ $ git reset --hard master~2
------------
You can make sure 'git show-branch' matches the state before
those two 'git resolve' you just did. Then, instead of running
two 'git resolve' commands in a row, you would pull these two
those two 'git merge' you just did. Then, instead of running
two 'git merge' commands in a row, you would pull these two
branch heads (this is known as 'making an Octopus'):
------------

24
INSTALL
View File

@ -5,10 +5,13 @@ Normally you can just do "make" followed by "make install", and that
will install the git programs in your own ~/bin/ directory. If you want
to do a global install, you can do
make prefix=/usr install
$ make prefix=/usr ;# as yourself
# make prefix=/usr install ;# as root
(or prefix=/usr/local, of course). Some day somebody may send me a RPM
spec file or something, and you can do "make rpm" or whatever.
(or prefix=/usr/local, of course). Just like any program suite
that uses $prefix, the built results have some paths encoded,
which are derived from $prefix, so "make all; make prefix=/usr
install" would not work.
Issues of note:
@ -46,6 +49,9 @@ Issues of note:
transfer, you are probabaly OK if you do not have
them.
- expat library; git-http-push uses it for remote lock
management over DAV. Similar to "curl" above, this is optional.
- "GNU diff" to generate patches. Of course, you don't _have_ to
generate patches if you don't want to, but let's face it, you'll
be wanting to. Or why did you get git in the first place?
@ -69,3 +75,15 @@ Issues of note:
history graphically
- "ssh" is used to push and pull over the net
- "perl" and POSIX-compliant shells are needed to use most of
the barebone Porcelainish scripts.
- "python" 2.3 or more recent; if you have 2.3, you may need
to build with "make WITH_OWN_SUBPROCESS_PY=YesPlease".
- Some platform specific issues are dealt with Makefile rules,
but depending on your specific installation, you may not
have all the libraries/tools needed, or you may have
necessary libraries at unusual locations. Please look at the
top of the Makefile to see what can be adjusted for your needs.

172
Makefile
View File

@ -6,12 +6,16 @@
# Define NO_OPENSSL environment variable if you do not have OpenSSL. You will
# miss out git-rev-list --merge-order. This also implies MOZILLA_SHA1.
#
# Define NO_CURL if you do not have curl installed. git-http-pull is not
# built, and you cannot use http:// and https:// transports.
# Define NO_CURL if you do not have curl installed. git-http-pull and
# git-http-push are not built, and you cannot use http:// and https://
# transports.
#
# Define CURLDIR=/foo/bar if your curl header and library files are in
# /foo/bar/include and /foo/bar/lib directories.
#
# Define NO_EXPAT if you do not have expat installed. git-http-push is
# not built, and you cannot push using http:// and https:// transports.
#
# Define NO_STRCASESTR if you don't have strcasestr.
#
# Define PPC_SHA1 environment variable when running make to make use of
@ -37,25 +41,23 @@
# 1461501637330902918203684832716283019655932542976 hashes do not give you
# sufficient guarantee that no collisions between objects will ever happen.
# DEFINES += -DCOLLISION_CHECK
# Define USE_NSEC below if you want git to care about sub-second file mtimes
# and ctimes. Note that you need recent glibc (at least 2.2.4) for this, and
# it will BREAK YOUR LOCAL DIFFS! show-diff and anything using it will likely
# randomly break unless your underlying filesystem supports those sub-second
# times (my ext3 doesn't).
# DEFINES += -DUSE_NSEC
# 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.
# DEFINES += -DUSE_STDEV
GIT_VERSION = 0.99.9k
GIT_VERSION = 0.99.9d
# CFLAGS and LDFLAGS are for the users to override from the command line.
CFLAGS = -g -O2 -Wall
ALL_CFLAGS = $(CFLAGS) $(PLATFORM_DEFINES) $(DEFINES)
LDFLAGS =
ALL_CFLAGS = $(CFLAGS)
ALL_LDFLAGS = $(LDFLAGS)
prefix = $(HOME)
bindir = $(prefix)/bin
@ -86,23 +88,29 @@ SCRIPT_SH = \
git-prune.sh git-pull.sh git-push.sh git-rebase.sh \
git-repack.sh git-request-pull.sh git-reset.sh \
git-resolve.sh git-revert.sh git-sh-setup.sh git-status.sh \
git-tag.sh git-verify-tag.sh git-whatchanged.sh git.sh \
git-tag.sh git-verify-tag.sh git-whatchanged.sh \
git-applymbox.sh git-applypatch.sh git-am.sh \
git-merge.sh git-merge-stupid.sh git-merge-octopus.sh \
git-merge-resolve.sh git-merge-ours.sh git-grep.sh
git-merge-resolve.sh git-merge-ours.sh git-grep.sh \
git-lost-found.sh
SCRIPT_PERL = \
git-archimport.perl git-cvsimport.perl git-relink.perl \
git-rename.perl git-shortlog.perl git-fmt-merge-msg.perl \
git-svnimport.perl git-mv.perl
git-shortlog.perl git-fmt-merge-msg.perl \
git-svnimport.perl git-mv.perl git-cvsexportcommit.perl
SCRIPT_PYTHON = \
git-merge-recursive.py
SCRIPTS = $(patsubst %.sh,%,$(SCRIPT_SH)) \
$(patsubst %.perl,%,$(SCRIPT_PERL)) \
$(patsubst %.py,%,$(SCRIPT_PYTHON)) \
gitk git-cherry-pick
# The ones that do not have to link with lcrypto nor lz.
SIMPLE_PROGRAMS = \
git-get-tar-commit-id$X git-mailinfo$X git-mailsplit$X \
git-stripspace$X git-var$X git-daemon$X
git-stripspace$X git-daemon$X
# ... and all the rest
PROGRAMS = \
@ -122,18 +130,36 @@ PROGRAMS = \
git-unpack-objects$X git-update-index$X git-update-server-info$X \
git-upload-pack$X git-verify-pack$X git-write-tree$X \
git-update-ref$X git-symbolic-ref$X git-check-ref-format$X \
git-name-rev$X $(SIMPLE_PROGRAMS)
git-name-rev$X git-pack-redundant$X git-repo-config$X git-var$X
# what 'all' will build and 'install' will install.
ALL_PROGRAMS = $(PROGRAMS) $(SIMPLE_PROGRAMS) $(SCRIPTS) git$X
# Backward compatibility -- to be removed after 1.0
PROGRAMS += git-ssh-pull$X git-ssh-push$X
GIT_LIST_TWEAK =
# Set paths to tools early so that they can be used for version tests.
ifndef SHELL_PATH
SHELL_PATH = /bin/sh
endif
ifndef PERL_PATH
PERL_PATH = /usr/bin/perl
endif
ifndef PYTHON_PATH
PYTHON_PATH = /usr/bin/python
endif
PYMODULES = \
gitMergeCommon.py
ifdef WITH_OWN_SUBPROCESS_PY
PYMODULES += compat/subprocess.py
else
ifneq ($(shell $(PYTHON_PATH) -c 'import subprocess;print"OK"' 2>/dev/null),OK)
PYMODULES += compat/subprocess.py
endif
endif
ifdef WITH_SEND_EMAIL
@ -185,6 +211,12 @@ uname_O := $(shell sh -c 'uname -o 2>/dev/null || echo not')
ifeq ($(uname_S),Darwin)
NEEDS_SSL_WITH_CRYPTO = YesPlease
NEEDS_LIBICONV = YesPlease
## fink
ALL_CFLAGS += -I/sw/include
ALL_LDFLAGS += -L/sw/lib
## darwinports
ALL_CFLAGS += -I/opt/local/include
ALL_LDFLAGS += -L/opt/local/lib
endif
ifeq ($(uname_S),SunOS)
NEEDS_SOCKET = YesPlease
@ -194,19 +226,29 @@ ifeq ($(uname_S),SunOS)
NO_STRCASESTR = YesPlease
INSTALL = ginstall
TAR = gtar
PLATFORM_DEFINES += -D__EXTENSIONS__
ALL_CFLAGS += -D__EXTENSIONS__
endif
ifeq ($(uname_O),Cygwin)
NO_STRCASESTR = YesPlease
NEEDS_LIBICONV = YesPlease
# There are conflicting reports about this.
# On some boxes NO_MMAP is needed, and not so elsewhere.
# Try uncommenting this if you see things break -- YMMV.
# NO_MMAP = YesPlease
NO_IPV6 = YesPlease
X = .exe
PLATFORM_DEFINES += -DUSE_SYMLINK_HEAD=0
ALL_CFLAGS += -DUSE_SYMLINK_HEAD=0
endif
ifeq ($(uname_S),OpenBSD)
NO_STRCASESTR = YesPlease
NEEDS_LIBICONV = YesPlease
PLATFORM_DEFINES += -I/usr/local/include -L/usr/local/lib
ALL_CFLAGS += -I/usr/local/include
ALL_LDFLAGS += -L/usr/local/lib
endif
ifeq ($(uname_S),NetBSD)
NEEDS_LIBICONV = YesPlease
ALL_CFLAGS += -I/usr/pkg/include
ALL_LDFLAGS += -L/usr/pkg/lib -Wl,-rpath,/usr/pkg/lib
endif
ifneq (,$(findstring arm,$(uname_M)))
ARM_SHA1 = YesPlease
@ -216,23 +258,20 @@ endif
ifndef NO_CURL
ifdef CURLDIR
# This is still problematic -- gcc does not want -R.
CFLAGS += -I$(CURLDIR)/include
# This is still problematic -- gcc does not always want -R.
ALL_CFLAGS += -I$(CURLDIR)/include
CURL_LIBCURL = -L$(CURLDIR)/lib -R$(CURLDIR)/lib -lcurl
else
CURL_LIBCURL = -lcurl
endif
PROGRAMS += git-http-fetch$X
endif
ifndef SHELL_PATH
SHELL_PATH = /bin/sh
endif
ifndef PERL_PATH
PERL_PATH = /usr/bin/perl
endif
ifndef PYTHON_PATH
PYTHON_PATH = /usr/bin/python
curl_check := $(shell (echo 070908; curl-config --vernum) | sort -r | sed -ne 2p)
ifeq "$(curl_check)" "070908"
ifndef NO_EXPAT
EXPAT_LIBEXPAT = -lexpat
PROGRAMS += git-http-push$X
endif
endif
endif
ifndef NO_OPENSSL
@ -240,13 +279,13 @@ ifndef NO_OPENSSL
OPENSSL_LIBSSL = -lssl
ifdef OPENSSLDIR
# Again this may be problematic -- gcc does not always want -R.
CFLAGS += -I$(OPENSSLDIR)/include
ALL_CFLAGS += -I$(OPENSSLDIR)/include
OPENSSL_LINK = -L$(OPENSSLDIR)/lib -R$(OPENSSLDIR)/lib
else
OPENSSL_LINK =
endif
else
DEFINES += -DNO_OPENSSL
ALL_CFLAGS += -DNO_OPENSSL
MOZILLA_SHA1 = 1
OPENSSL_LIBSSL =
endif
@ -258,7 +297,7 @@ endif
ifdef NEEDS_LIBICONV
ifdef ICONVDIR
# Again this may be problematic -- gcc does not always want -R.
CFLAGS += -I$(ICONVDIR)/include
ALL_CFLAGS += -I$(ICONVDIR)/include
ICONV_LINK = -L$(ICONVDIR)/lib -R$(ICONVDIR)/lib
else
ICONV_LINK =
@ -276,15 +315,15 @@ ifdef NEEDS_NSL
SIMPLE_LIB += -lnsl
endif
ifdef NO_STRCASESTR
DEFINES += -Dstrcasestr=gitstrcasestr -DNO_STRCASESTR=1
ALL_CFLAGS += -Dstrcasestr=gitstrcasestr -DNO_STRCASESTR=1
LIB_OBJS += compat/strcasestr.o
endif
ifdef NO_MMAP
DEFINES += -Dmmap=gitfakemmap -Dmunmap=gitfakemunmap -DNO_MMAP
ALL_CFLAGS += -Dmmap=gitfakemmap -Dmunmap=gitfakemunmap -DNO_MMAP
LIB_OBJS += compat/mmap.o
endif
ifdef NO_IPV6
DEFINES += -DNO_IPV6 -Dsockaddr_storage=sockaddr_in
ALL_CFLAGS += -DNO_IPV6 -Dsockaddr_storage=sockaddr_in
endif
ifdef PPC_SHA1
@ -305,31 +344,22 @@ endif
endif
endif
DEFINES += -DSHA1_HEADER=$(call shellquote,$(SHA1_HEADER))
SCRIPTS = $(patsubst %.sh,%,$(SCRIPT_SH)) \
$(patsubst %.perl,%,$(SCRIPT_PERL)) \
$(patsubst %.py,%,$(SCRIPT_PYTHON)) \
gitk git-cherry-pick
ALL_CFLAGS += -DSHA1_HEADER=$(call shellquote,$(SHA1_HEADER))
export prefix TAR INSTALL DESTDIR SHELL_PATH template_dir
### Build rules
all: $(PROGRAMS) $(SCRIPTS)
all: $(ALL_PROGRAMS)
all:
$(MAKE) -C templates
git: git.sh Makefile
rm -f $@+ $@
sed -e '1s|#!.*/sh|#!$(call shq,$(SHELL_PATH))|' \
-e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \
-e 's/@@X@@/$(X)/g' \
$(GIT_LIST_TWEAK) <$@.sh >$@+
chmod +x $@+
mv $@+ $@
# Only use $(CFLAGS). We don't need anything else.
git$(X): git.c Makefile
$(CC) -DGIT_EXEC_PATH='"$(bindir)"' -DGIT_VERSION='"$(GIT_VERSION)"' \
$(CFLAGS) $< -o $@
$(filter-out git,$(patsubst %.sh,%,$(SCRIPT_SH))) : % : %.sh
$(patsubst %.sh,%,$(SCRIPT_SH)) : % : %.sh
rm -f $@
sed -e '1s|#!.*/sh|#!$(call shq,$(SHELL_PATH))|' \
-e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \
@ -360,14 +390,16 @@ git-cherry-pick: git-revert
$(CC) -o $*.o -c $(ALL_CFLAGS) $<
git-%$X: %.o $(LIB_FILE)
$(CC) $(ALL_CFLAGS) -o $@ $(filter %.o,$^) $(LIBS)
$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(LIBS)
git-mailinfo$X : SIMPLE_LIB += $(LIB_4_ICONV)
$(SIMPLE_PROGRAMS) : $(LIB_FILE)
$(SIMPLE_PROGRAMS) : git-%$X : %.o
$(CC) $(ALL_CFLAGS) -o $@ $(filter %.o,$^) $(LIB_FILE) $(SIMPLE_LIB)
$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \
$(LIB_FILE) $(SIMPLE_LIB)
git-http-fetch$X: fetch.o
git-http-fetch$X: fetch.o http.o
git-http-push$X: http.o
git-local-fetch$X: fetch.o
git-ssh-fetch$X: rsh.o fetch.o
git-ssh-upload$X: rsh.o
@ -375,6 +407,7 @@ git-ssh-pull$X: rsh.o fetch.o
git-ssh-push$X: rsh.o
git-http-fetch$X: LIBS += $(CURL_LIBCURL)
git-http-push$X: LIBS += $(CURL_LIBCURL) $(EXPAT_LIBEXPAT)
git-rev-list$X: LIBS += $(OPENSSL_LIBSSL)
init-db.o: init-db.c
@ -398,10 +431,10 @@ test: all
$(MAKE) -C t/ all
test-date$X: test-date.c date.o ctype.o
$(CC) $(ALL_CFLAGS) -o $@ test-date.c date.o ctype.o
$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) test-date.c date.o ctype.o
test-delta$X: test-delta.c diff-delta.o patch-delta.o
$(CC) $(ALL_CFLAGS) -o $@ $^
$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $^
check:
for i in *.c; do sparse $(ALL_CFLAGS) $(SPARSE_FLAGS) $$i; done
@ -410,9 +443,9 @@ check:
### Installation rules
install: $(PROGRAMS) $(SCRIPTS)
install: all
$(INSTALL) -d -m755 $(call shellquote,$(DESTDIR)$(bindir))
$(INSTALL) $(PROGRAMS) $(SCRIPTS) $(call shellquote,$(DESTDIR)$(bindir))
$(INSTALL) $(ALL_PROGRAMS) $(call shellquote,$(DESTDIR)$(bindir))
$(MAKE) -C templates install
$(INSTALL) -d -m755 $(call shellquote,$(DESTDIR)$(GIT_PYTHON_DIR))
$(INSTALL) $(PYMODULES) $(call shellquote,$(DESTDIR)$(GIT_PYTHON_DIR))
@ -425,20 +458,20 @@ install-doc:
### Maintainer's dist rules
git-core.spec: git-core.spec.in Makefile
git.spec: git.spec.in Makefile
sed -e 's/@@VERSION@@/$(GIT_VERSION)/g' < $< > $@
GIT_TARNAME=git-core-$(GIT_VERSION)
dist: git-core.spec git-tar-tree
GIT_TARNAME=git-$(GIT_VERSION)
dist: git.spec git-tar-tree
./git-tar-tree HEAD $(GIT_TARNAME) > $(GIT_TARNAME).tar
@mkdir -p $(GIT_TARNAME)
@cp git-core.spec $(GIT_TARNAME)
$(TAR) rf $(GIT_TARNAME).tar $(GIT_TARNAME)/git-core.spec
@cp git.spec $(GIT_TARNAME)
$(TAR) rf $(GIT_TARNAME).tar $(GIT_TARNAME)/git.spec
@rm -rf $(GIT_TARNAME)
gzip -f -9 $(GIT_TARNAME).tar
rpm: dist
$(RPMBUILD) -ta git-core-$(GIT_VERSION).tar.gz
$(RPMBUILD) -ta $(GIT_TARNAME).tar.gz
deb: dist
rm -rf $(GIT_TARNAME)
@ -449,13 +482,14 @@ deb: dist
### Cleaning rules
clean:
rm -f *.o mozilla-sha1/*.o ppc/*.o compat/*.o $(PROGRAMS) $(LIB_FILE)
rm -f *.o mozilla-sha1/*.o arm/*.o ppc/*.o compat/*.o $(LIB_FILE)
rm -f $(PROGRAMS) $(SIMPLE_PROGRAMS) git$X
rm -f $(filter-out gitk,$(SCRIPTS))
rm -f git-core.spec *.pyc *.pyo
rm -f *.spec *.pyc *.pyo
rm -rf $(GIT_TARNAME)
rm -f $(GIT_TARNAME).tar.gz git-core_$(GIT_VERSION)-*.tar.gz
rm -f git-core_$(GIT_VERSION)-*.deb git-core_$(GIT_VERSION)-*.dsc
rm -f git-tk_$(GIT_VERSION)-*.deb
rm -f git-core_$(GIT_VERSION)-*.dsc
rm -f git-*_$(GIT_VERSION)-*.deb
$(MAKE) -C Documentation/ clean
$(MAKE) -C templates clean
$(MAKE) -C t/ clean

6
README
View File

@ -396,8 +396,8 @@ git-commit-tree will return the name of the object that represents
that commit, and you should save it away for later use. Normally,
you'd commit a new `HEAD` state, and while git doesn't care where you
save the note about that state, in practice we tend to just write the
result to the file `.git/HEAD`, so that we can always see what the
last committed state was.
result to the file pointed at by `.git/HEAD`, so that we can always see
what the last committed state was.
Here is an ASCII art by Jon Loeliger that illustrates how
various pieces fit together.
@ -464,7 +464,7 @@ tend to be small and fairly self-explanatory. In particular, if you
follow the convention of having the top commit name in `.git/HEAD`,
you can do
git-cat-file commit $(cat .git/HEAD)
git-cat-file commit HEAD
to see what the top commit was.

137
apply.c
View File

@ -16,6 +16,7 @@
// --numstat does numeric diffstat, and doesn't actually apply
// --index-info shows the old and new index info for paths if available.
//
static int allow_binary_replacement = 0;
static int check_index = 0;
static int write_index = 0;
static int diffstat = 0;
@ -23,10 +24,11 @@ static int numstat = 0;
static int summary = 0;
static int check = 0;
static int apply = 1;
static int no_add = 0;
static int show_index_info = 0;
static int line_termination = '\n';
static const char apply_usage[] =
"git-apply [--stat] [--numstat] [--summary] [--check] [--index] [--apply] [--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
@ -53,7 +55,7 @@ struct fragment {
struct patch {
char *new_name, *old_name, *def_name;
unsigned int old_mode, new_mode;
int is_rename, is_copy, is_new, is_delete;
int is_rename, is_copy, is_new, is_delete, is_binary;
int lines_added, lines_deleted;
int score;
struct fragment *fragments;
@ -369,7 +371,7 @@ static int gitdiff_index(const char *line, struct patch *patch)
int len;
ptr = strchr(line, '.');
if (!ptr || ptr[1] != '.' || 40 <= ptr - line)
if (!ptr || ptr[1] != '.' || 40 < ptr - line)
return 0;
len = ptr - line;
memcpy(patch->old_sha1_prefix, line, len);
@ -383,7 +385,7 @@ static int gitdiff_index(const char *line, struct patch *patch)
ptr = eol;
len = ptr - line;
if (40 <= len)
if (40 < len)
return 0;
memcpy(patch->new_sha1_prefix, line, len);
patch->new_sha1_prefix[len] = 0;
@ -890,8 +892,36 @@ static int parse_chunk(char *buffer, unsigned long size, struct patch *patch)
patchsize = parse_single_patch(buffer + offset + hdrsize, size - offset - hdrsize, patch);
if (!patchsize && !metadata_changes(patch))
die("patch with only garbage at line %d", linenr);
if (!patchsize) {
static const char *binhdr[] = {
"Binary files ",
"Files ",
NULL,
};
int i;
int hd = hdrsize + offset;
unsigned long llen = linelen(buffer + hd, size - hd);
if (!memcmp(" differ\n", buffer + hd + llen - 8, 8))
for (i = 0; binhdr[i]; i++) {
int len = strlen(binhdr[i]);
if (len < size - hd &&
!memcmp(binhdr[i], buffer + hd, len)) {
patch->is_binary = 1;
break;
}
}
/* Empty patch cannot be applied if:
* - it is a binary patch and we do not do binary_replace, or
* - text patch without metadata change
*/
if ((apply || check) &&
(patch->is_binary
? !allow_binary_replacement
: !metadata_changes(patch)))
die("patch with only garbage at line %d", linenr);
}
return offset + hdrsize + patchsize;
}
@ -949,9 +979,12 @@ static void show_stats(struct patch *patch)
add = (add * max + max_change / 2) / max_change;
del = total - add;
}
printf(" %s%-*s |%5d %.*s%.*s\n", prefix,
len, name, patch->lines_added + patch->lines_deleted,
add, pluses, del, minuses);
if (patch->is_binary)
printf(" %s%-*s | Bin\n", prefix, len, name);
else
printf(" %s%-*s |%5d %.*s%.*s\n", prefix,
len, name, patch->lines_added + patch->lines_deleted,
add, pluses, del, minuses);
if (qname)
free(qname);
}
@ -1099,8 +1132,10 @@ static int apply_one_fragment(struct buffer_desc *desc, struct fragment *frag)
break;
/* Fall-through for ' ' */
case '+':
memcpy(new + newsize, patch + 1, plen);
newsize += plen;
if (*patch != '+' || !no_add) {
memcpy(new + newsize, patch + 1, plen);
newsize += plen;
}
break;
case '@': case '\\':
/* Ignore it, we already handled it */
@ -1138,10 +1173,77 @@ static int apply_one_fragment(struct buffer_desc *desc, struct fragment *frag)
static int apply_fragments(struct buffer_desc *desc, struct patch *patch)
{
struct fragment *frag = patch->fragments;
const char *name = patch->old_name ? patch->old_name : patch->new_name;
if (patch->is_binary) {
unsigned char sha1[20];
if (!allow_binary_replacement)
return error("cannot apply binary patch to '%s' "
"without --allow-binary-replacement",
name);
/* For safety, we require patch index line to contain
* full 40-byte textual SHA1 for old and new, at least for now.
*/
if (strlen(patch->old_sha1_prefix) != 40 ||
strlen(patch->new_sha1_prefix) != 40 ||
get_sha1_hex(patch->old_sha1_prefix, sha1) ||
get_sha1_hex(patch->new_sha1_prefix, sha1))
return error("cannot apply binary patch to '%s' "
"without full index line", name);
if (patch->old_name) {
unsigned char hdr[50];
int hdrlen;
/* See if the old one matches what the patch
* applies to.
*/
write_sha1_file_prepare(desc->buffer, desc->size,
"blob", sha1, hdr, &hdrlen);
if (strcmp(sha1_to_hex(sha1), patch->old_sha1_prefix))
return error("the patch applies to '%s' (%s), "
"which does not match the "
"current contents.",
name, sha1_to_hex(sha1));
}
else {
/* Otherwise, the old one must be empty. */
if (desc->size)
return error("the patch applies to an empty "
"'%s' but it is not empty", name);
}
/* For now, we do not record post-image data in the patch,
* and require the object already present in the recipient's
* object database.
*/
if (desc->buffer) {
free(desc->buffer);
desc->alloc = desc->size = 0;
}
get_sha1_hex(patch->new_sha1_prefix, sha1);
if (memcmp(sha1, null_sha1, 20)) {
char type[10];
unsigned long size;
desc->buffer = read_sha1_file(sha1, type, &size);
if (!desc->buffer)
return error("the necessary postimage %s for "
"'%s' does not exist",
patch->new_sha1_prefix, name);
desc->alloc = desc->size = size;
}
return 0;
}
while (frag) {
if (apply_one_fragment(desc, frag) < 0)
return error("patch failed: %s:%ld", patch->old_name, frag->oldpos);
return error("patch failed: %s:%ld",
name, frag->oldpos);
frag = frag->next;
}
return 0;
@ -1183,6 +1285,7 @@ static int check_patch(struct patch *patch)
struct stat st;
const char *old_name = patch->old_name;
const char *new_name = patch->new_name;
const char *name = old_name ? old_name : new_name;
if (old_name) {
int changed;
@ -1257,7 +1360,7 @@ static int check_patch(struct patch *patch)
}
if (apply_data(patch, &st) < 0)
return error("%s: patch does not apply", old_name);
return error("%s: patch does not apply", name);
return 0;
}
@ -1697,11 +1800,19 @@ int main(int argc, char **argv)
excludes = x;
continue;
}
if (!strcmp(arg, "--no-add")) {
no_add = 1;
continue;
}
if (!strcmp(arg, "--stat")) {
apply = 0;
diffstat = 1;
continue;
}
if (!strcmp(arg, "--allow-binary-replacement")) {
allow_binary_replacement = 1;
continue;
}
if (!strcmp(arg, "--numstat")) {
apply = 0;
numstat = 1;

11
cache.h
View File

@ -179,6 +179,8 @@ extern int commit_index_file(struct cache_file *);
extern void rollback_index_file(struct cache_file *);
extern int trust_executable_bit;
extern int only_use_symrefs;
extern int diff_rename_limit_default;
#define MTIME_CHANGED 0x0001
#define CTIME_CHANGED 0x0002
@ -201,6 +203,7 @@ int git_mkstemp(char *path, size_t n, const char *template);
int safe_create_leading_directories(char *path);
char *safe_strncpy(char *, const char *, size_t);
char *enter_repo(char *path, int strict);
/* Read and unpack a sha1 file into memory, write memory to a sha1 file */
extern int unpack_sha1_header(z_stream *stream, void *map, unsigned long mapsize, void *buffer, unsigned long size);
@ -257,11 +260,11 @@ extern void *read_object_with_reference(const unsigned char *sha1,
const char *show_date(unsigned long time, int timezone);
int parse_date(const char *date, char *buf, int bufsize);
void datestamp(char *buf, int bufsize);
unsigned long approxidate(const char *);
extern int setup_ident(void);
extern char *get_ident(const char *name, const char *email, const char *date_str);
extern char *git_author_info(void);
extern char *git_committer_info(void);
extern const char *git_author_info(void);
extern const char *git_committer_info(void);
static inline void *xmalloc(size_t size)
{
@ -383,6 +386,8 @@ extern int git_default_config(const char *, const char *);
extern int git_config(config_fn_t fn);
extern int git_config_int(const char *, const char *);
extern int git_config_bool(const char *, const char *);
extern int git_config_set(const char *, const char *);
extern int git_config_set_multivar(const char *, const char *, const char *, int);
#define MAX_GITNAME (1000)
extern char git_default_email[MAX_GITNAME];

View File

@ -34,6 +34,8 @@ enum cmit_fmt get_commit_format(const char *arg)
return CMIT_FMT_SHORT;
if (!strcmp(arg, "=full"))
return CMIT_FMT_FULL;
if (!strcmp(arg, "=fuller"))
return CMIT_FMT_FULLER;
if (!strcmp(arg, "=oneline"))
return CMIT_FMT_ONELINE;
die("invalid --pretty format");
@ -202,6 +204,7 @@ int parse_commit_buffer(struct commit *item, void *buffer, unsigned long size)
unsigned char parent[20];
struct commit_list **pptr;
struct commit_graft *graft;
unsigned n_refs = 0;
if (item->object.parsed)
return 0;
@ -212,7 +215,7 @@ int parse_commit_buffer(struct commit *item, void *buffer, unsigned long size)
return error("bad tree pointer in commit %s\n", sha1_to_hex(item->object.sha1));
item->tree = lookup_tree(parent);
if (item->tree)
add_ref(&item->object, &item->tree->object);
n_refs++;
bufptr += 46; /* "tree " + "hex sha1" + "\n" */
pptr = &item->parents;
@ -228,7 +231,7 @@ int parse_commit_buffer(struct commit *item, void *buffer, unsigned long size)
new_parent = lookup_commit(parent);
if (new_parent) {
pptr = &commit_list_insert(new_parent, pptr)->next;
add_ref(&item->object, &new_parent->object);
n_refs++;
}
}
if (graft) {
@ -239,10 +242,22 @@ int parse_commit_buffer(struct commit *item, void *buffer, unsigned long size)
if (!new_parent)
continue;
pptr = &commit_list_insert(new_parent, pptr)->next;
add_ref(&item->object, &new_parent->object);
n_refs++;
}
}
item->date = parse_commit_date(bufptr);
if (track_object_refs) {
unsigned i = 0;
struct commit_list *p;
struct object_refs *refs = alloc_object_refs(n_refs);
if (item->tree)
refs->ref[i++] = &item->tree->object;
for (p = item->parents; p; p = p->next)
refs->ref[i++] = &p->item->object;
set_object_refs(&item->object, refs);
}
return 0;
}
@ -361,6 +376,7 @@ static int add_user_info(const char *what, enum cmit_fmt fmt, char *buf, const c
int namelen;
unsigned long time;
int tz, ret;
const char *filler = " ";
if (fmt == CMIT_FMT_ONELINE)
return 0;
@ -371,9 +387,20 @@ static int add_user_info(const char *what, enum cmit_fmt fmt, char *buf, const c
time = strtoul(date, &date, 10);
tz = strtol(date, NULL, 10);
ret = sprintf(buf, "%s: %.*s\n", what, namelen, line);
if (fmt == CMIT_FMT_MEDIUM)
ret = sprintf(buf, "%s: %.*s%.*s\n", what,
(fmt == CMIT_FMT_FULLER) ? 4 : 0,
filler, namelen, line);
switch (fmt) {
case CMIT_FMT_MEDIUM:
ret += sprintf(buf + ret, "Date: %s\n", show_date(time, tz));
break;
case CMIT_FMT_FULLER:
ret += sprintf(buf + ret, "%sDate: %s\n", what, show_date(time, tz));
break;
default:
/* notin' */
break;
}
return ret;
}
@ -448,12 +475,21 @@ unsigned long pretty_print_commit(enum cmit_fmt fmt, const char *msg, unsigned l
die("bad parent line in commit");
offset += add_parent_info(fmt, buf + offset, line, ++parents);
}
/*
* MEDIUM == DEFAULT shows only author with dates.
* FULL shows both authors but not dates.
* FULLER shows both authors and dates.
*/
if (!memcmp(line, "author ", 7))
offset += add_user_info("Author", fmt, buf + offset, line + 7);
if (fmt == CMIT_FMT_FULL) {
if (!memcmp(line, "committer ", 10))
offset += add_user_info("Commit", fmt, buf + offset, line + 10);
}
offset += add_user_info("Author", fmt,
buf + offset,
line + 7);
if (!memcmp(line, "committer ", 10) &&
(fmt == CMIT_FMT_FULL || fmt == CMIT_FMT_FULLER))
offset += add_user_info("Commit", fmt,
buf + offset,
line + 10);
continue;
}
@ -513,7 +549,7 @@ int count_parents(struct commit * commit)
void sort_in_topological_order(struct commit_list ** list)
{
struct commit_list * next = *list;
struct commit_list * work = NULL;
struct commit_list * work = NULL, **insert;
struct commit_list ** pptr = list;
struct sort_node * nodes;
struct sort_node * next_nodes;
@ -557,11 +593,12 @@ void sort_in_topological_order(struct commit_list ** list)
* the tips serve as a starting set for the work queue.
*/
next=*list;
insert = &work;
while (next) {
struct sort_node * node = (struct sort_node *)next->item->object.util;
if (node->indegree == 0) {
commit_list_insert(next->item, &work);
insert = &commit_list_insert(next->item, insert)->next;
}
next=next->next;
}

View File

@ -43,6 +43,7 @@ enum cmit_fmt {
CMIT_FMT_DEFAULT = CMIT_FMT_MEDIUM,
CMIT_FMT_SHORT,
CMIT_FMT_FULL,
CMIT_FMT_FULLER,
CMIT_FMT_ONELINE,
};

340
config.c
View File

@ -1,5 +1,12 @@
/*
* GIT - The information manager from hell
*
* Copyright (C) Linus Torvalds, 2005
* Copyright (C) Johannes Schindelin, 2005
*
*/
#include "cache.h"
#include <regex.h>
#define MAXNAME (256)
@ -136,7 +143,7 @@ static int get_base_var(char *name)
return -1;
if (c == ']')
return baselen;
if (!isalnum(c))
if (!isalnum(c) && c != '.')
return -1;
if (baselen > MAXNAME / 2)
return -1;
@ -214,6 +221,11 @@ int git_default_config(const char *var, const char *value)
return 0;
}
if (!strcmp(var, "core.symrefsonly")) {
only_use_symrefs = git_config_bool(var, value);
return 0;
}
if (!strcmp(var, "user.name")) {
strncpy(git_default_name, value, sizeof(git_default_name));
return 0;
@ -242,3 +254,327 @@ int git_config(config_fn_t fn)
}
return ret;
}
/*
* Find all the stuff for git_config_set() below.
*/
#define MAX_MATCHES 512
static struct {
int baselen;
char* key;
int do_not_match;
regex_t* value_regex;
int multi_replace;
off_t offset[MAX_MATCHES];
enum { START, SECTION_SEEN, SECTION_END_SEEN, KEY_SEEN } state;
int seen;
} store;
static int matches(const char* key, const char* value)
{
return !strcmp(key, store.key) &&
(store.value_regex == NULL ||
(store.do_not_match ^
!regexec(store.value_regex, value, 0, NULL, 0)));
}
static int store_aux(const char* key, const char* value)
{
switch (store.state) {
case KEY_SEEN:
if (matches(key, value)) {
if (store.seen == 1 && store.multi_replace == 0) {
fprintf(stderr,
"Warning: %s has multiple values\n",
key);
} else if (store.seen >= MAX_MATCHES) {
fprintf(stderr, "Too many matches\n");
return 1;
}
store.offset[store.seen] = ftell(config_file);
store.seen++;
}
break;
case SECTION_SEEN:
if (strncmp(key, store.key, store.baselen+1)) {
store.state = SECTION_END_SEEN;
break;
} else
/* do not increment matches: this is no match */
store.offset[store.seen] = ftell(config_file);
/* fallthru */
case SECTION_END_SEEN:
case START:
if (matches(key, value)) {
store.offset[store.seen] = ftell(config_file);
store.state = KEY_SEEN;
store.seen++;
} else if(!strncmp(key, store.key, store.baselen))
store.state = SECTION_SEEN;
}
return 0;
}
static void store_write_section(int fd, const char* key)
{
write(fd, "[", 1);
write(fd, key, store.baselen);
write(fd, "]\n", 2);
}
static void store_write_pair(int fd, const char* key, const char* value)
{
int i;
write(fd, "\t", 1);
write(fd, key+store.baselen+1,
strlen(key+store.baselen+1));
write(fd, " = ", 3);
for (i = 0; value[i]; i++)
switch (value[i]) {
case '\n': write(fd, "\\n", 2); break;
case '\t': write(fd, "\\t", 2); break;
case '"': case '\\': write(fd, "\\", 1);
default: write(fd, value+i, 1);
}
write(fd, "\n", 1);
}
static int find_beginning_of_line(const char* contents, int size,
int offset_, int* found_bracket)
{
int equal_offset = size, bracket_offset = size;
int offset;
for (offset = offset_-2; offset > 0
&& contents[offset] != '\n'; offset--)
switch (contents[offset]) {
case '=': equal_offset = offset; break;
case ']': bracket_offset = offset; break;
}
if (bracket_offset < equal_offset) {
*found_bracket = 1;
offset = bracket_offset+1;
} else
offset++;
return offset;
}
int git_config_set(const char* key, const char* value)
{
return git_config_set_multivar(key, value, NULL, 0);
}
/*
* If value==NULL, unset in (remove from) config,
* if value_regex!=NULL, disregard key/value pairs where value does not match.
* if multi_replace==0, nothing, or only one matching key/value is replaced,
* else all matching key/values (regardless how many) are removed,
* before the new pair is written.
*
* Returns 0 on success.
*
* This function does this:
*
* - it locks the config file by creating ".git/config.lock"
*
* - it then parses the config using store_aux() as validator to find
* the position on the key/value pair to replace. If it is to be unset,
* it must be found exactly once.
*
* - the config file is mmap()ed and the part before the match (if any) is
* written to the lock file, then the changed part and the rest.
*
* - the config file is removed and the lock file rename()d to it.
*
*/
int git_config_set_multivar(const char* key, const char* value,
const char* value_regex, int multi_replace)
{
int i;
struct stat st;
int fd;
char* config_filename = strdup(git_path("config"));
char* lock_file = strdup(git_path("config.lock"));
const char* last_dot = strrchr(key, '.');
/*
* Since "key" actually contains the section name and the real
* key name separated by a dot, we have to know where the dot is.
*/
if (last_dot == NULL) {
fprintf(stderr, "key does not contain a section: %s\n", key);
return 2;
}
store.baselen = last_dot - key;
store.multi_replace = multi_replace;
/*
* Validate the key and while at it, lower case it for matching.
*/
store.key = (char*)malloc(strlen(key)+1);
for (i = 0; key[i]; i++)
if (i != store.baselen &&
((!isalnum(key[i]) && key[i] != '.') ||
(i == store.baselen+1 && !isalpha(key[i])))) {
fprintf(stderr, "invalid key: %s\n", key);
free(store.key);
return 1;
} else
store.key[i] = tolower(key[i]);
store.key[i] = 0;
/*
* The lock_file serves a purpose in addition to locking: the new
* contents of .git/config will be written into it.
*/
fd = open(lock_file, O_WRONLY | O_CREAT | O_EXCL, 0666);
if (fd < 0) {
fprintf(stderr, "could not lock config file\n");
free(store.key);
return -1;
}
/*
* If .git/config does not exist yet, write a minimal version.
*/
if (stat(config_filename, &st)) {
static const char contents[] =
"#\n"
"# This is the config file\n"
"#\n"
"\n";
free(store.key);
/* if nothing to unset, error out */
if (value == NULL) {
close(fd);
unlink(lock_file);
return 5;
}
store.key = (char*)key;
write(fd, contents, sizeof(contents)-1);
store_write_section(fd, key);
store_write_pair(fd, key, value);
} else{
int in_fd;
char* contents;
int i, copy_begin, copy_end, new_line = 0;
if (value_regex == NULL)
store.value_regex = NULL;
else {
if (value_regex[0] == '!') {
store.do_not_match = 1;
value_regex++;
} else
store.do_not_match = 0;
store.value_regex = (regex_t*)malloc(sizeof(regex_t));
if (regcomp(store.value_regex, value_regex,
REG_EXTENDED)) {
fprintf(stderr, "Invalid pattern: %s",
value_regex);
free(store.value_regex);
return 6;
}
}
store.offset[0] = 0;
store.state = START;
store.seen = 0;
/*
* After this, store.offset will contain the *end* offset
* of the last match, or remain at 0 if no match was found.
* As a side effect, we make sure to transform only a valid
* existing config file.
*/
if (git_config(store_aux)) {
fprintf(stderr, "invalid config file\n");
free(store.key);
if (store.value_regex != NULL) {
regfree(store.value_regex);
free(store.value_regex);
}
return 3;
}
free(store.key);
if (store.value_regex != NULL) {
regfree(store.value_regex);
free(store.value_regex);
}
/* if nothing to unset, or too many matches, error out */
if ((store.seen == 0 && value == NULL) ||
(store.seen > 1 && multi_replace == 0)) {
close(fd);
unlink(lock_file);
return 5;
}
in_fd = open(config_filename, O_RDONLY, 0666);
contents = mmap(NULL, st.st_size, PROT_READ,
MAP_PRIVATE, in_fd, 0);
close(in_fd);
if (store.seen == 0)
store.seen = 1;
for (i = 0, copy_begin = 0; i < store.seen; i++) {
if (store.offset[i] == 0) {
store.offset[i] = copy_end = st.st_size;
} else if (store.state != KEY_SEEN) {
copy_end = store.offset[i];
} else
copy_end = find_beginning_of_line(
contents, st.st_size,
store.offset[i]-2, &new_line);
/* write the first part of the config */
if (copy_end > copy_begin) {
write(fd, contents + copy_begin,
copy_end - copy_begin);
if (new_line)
write(fd, "\n", 1);
}
copy_begin = store.offset[i];
}
/* write the pair (value == NULL means unset) */
if (value != NULL) {
if (store.state == START)
store_write_section(fd, key);
store_write_pair(fd, key, value);
}
/* write the rest of the config */
if (copy_begin < st.st_size)
write(fd, contents + copy_begin,
st.st_size - copy_begin);
munmap(contents, st.st_size);
unlink(config_filename);
}
close(fd);
if (rename(lock_file, config_filename) < 0) {
fprintf(stderr, "Could not rename the lock file?\n");
return 4;
}
return 0;
}

166
connect.c
View File

@ -427,7 +427,7 @@ static int git_tcp_connect(int fd[2], const char *prog, char *host, char *path)
memset(&sa, 0, sizeof sa);
sa.sin_family = he->h_addrtype;
sa.sin_port = htons(nport);
memcpy(&sa.sin_addr, ap, he->h_length);
memcpy(&sa.sin_addr, *ap, he->h_length);
if (connect(sockfd, (struct sockaddr *)&sa, sizeof sa) < 0) {
close(sockfd);
@ -448,42 +448,162 @@ static int git_tcp_connect(int fd[2], const char *prog, char *host, char *path)
#endif /* NO_IPV6 */
static char *git_proxy_command = NULL;
static const char *rhost_name = NULL;
static int rhost_len;
static int git_proxy_command_options(const char *var, const char *value)
{
if (!strcmp(var, "core.gitproxy")) {
const char *for_pos;
int matchlen = -1;
int hostlen;
if (git_proxy_command)
return 0;
/* [core]
* ;# matches www.kernel.org as well
* gitproxy = netcatter-1 for kernel.org
* gitproxy = netcatter-2 for sample.xz
* gitproxy = netcatter-default
*/
for_pos = strstr(value, " for ");
if (!for_pos)
/* matches everybody */
matchlen = strlen(value);
else {
hostlen = strlen(for_pos + 5);
if (rhost_len < hostlen)
matchlen = -1;
else if (!strncmp(for_pos + 5,
rhost_name + rhost_len - hostlen,
hostlen) &&
((rhost_len == hostlen) ||
rhost_name[rhost_len - hostlen -1] == '.'))
matchlen = for_pos - value;
else
matchlen = -1;
}
if (0 <= matchlen) {
/* core.gitproxy = none for kernel.org */
if (matchlen == 4 &&
!memcmp(value, "none", 4))
matchlen = 0;
git_proxy_command = xmalloc(matchlen + 1);
memcpy(git_proxy_command, value, matchlen);
git_proxy_command[matchlen] = 0;
}
return 0;
}
return git_default_config(var, value);
}
static int git_use_proxy(const char *host)
{
rhost_name = host;
rhost_len = strlen(host);
git_proxy_command = getenv("GIT_PROXY_COMMAND");
git_config(git_proxy_command_options);
rhost_name = NULL;
return (git_proxy_command && *git_proxy_command);
}
static int git_proxy_connect(int fd[2], const char *prog, char *host, char *path)
{
char *port = STR(DEFAULT_GIT_PORT);
char *colon, *end;
int pipefd[2][2];
pid_t pid;
if (host[0] == '[') {
end = strchr(host + 1, ']');
if (end) {
*end = 0;
end++;
host++;
} else
end = host;
} else
end = host;
colon = strchr(end, ':');
if (colon) {
*colon = 0;
port = colon + 1;
}
if (pipe(pipefd[0]) < 0 || pipe(pipefd[1]) < 0)
die("unable to create pipe pair for communication");
pid = fork();
if (!pid) {
dup2(pipefd[1][0], 0);
dup2(pipefd[0][1], 1);
close(pipefd[0][0]);
close(pipefd[0][1]);
close(pipefd[1][0]);
close(pipefd[1][1]);
execlp(git_proxy_command, git_proxy_command, host, port, NULL);
die("exec failed");
}
fd[0] = pipefd[0][0];
fd[1] = pipefd[1][1];
close(pipefd[0][1]);
close(pipefd[1][0]);
packet_write(fd[1], "%s %s\n", prog, path);
return pid;
}
/*
* Yeah, yeah, fixme. Need to pass in the heads etc.
*/
int git_connect(int fd[2], char *url, const char *prog)
{
char command[1024];
char *host, *path;
char *colon;
char *host, *path = url;
char *colon = NULL;
int pipefd[2][2];
pid_t pid;
enum protocol protocol;
enum protocol protocol = PROTO_LOCAL;
host = NULL;
path = url;
colon = strchr(url, ':');
protocol = PROTO_LOCAL;
if (colon) {
*colon = 0;
host = strstr(url, "://");
if(host) {
*host = '\0';
protocol = get_protocol(url);
host += 3;
path = strchr(host, '/');
}
else {
host = url;
path = colon+1;
protocol = PROTO_SSH;
if (!memcmp(path, "//", 2)) {
char *slash = strchr(path + 2, '/');
if (slash) {
int nr = slash - path - 2;
memmove(path, path+2, nr);
path[nr] = 0;
protocol = get_protocol(url);
host = path;
path = slash;
}
if ((colon = strchr(host, ':'))) {
protocol = PROTO_SSH;
*colon = '\0';
path = colon + 1;
}
}
if (protocol == PROTO_GIT)
if (!path || !*path)
die("No path specified. See 'man git-pull' for valid url syntax");
/*
* null-terminate hostname and point path to ~ for URL's like this:
* ssh://host.xz/~user/repo
*/
if (protocol != PROTO_LOCAL && host != url) {
char *ptr = path;
if (path[1] == '~')
path++;
else
path = strdup(ptr);
*ptr = '\0';
}
if (protocol == PROTO_GIT) {
if (git_use_proxy(host))
return git_proxy_connect(fd, prog, host, path);
return git_tcp_connect(fd, prog, host, path);
}
if (pipe(pipefd[0]) < 0 || pipe(pipefd[1]) < 0)
die("unable to create pipe pair for communication");

151
daemon.c
View File

@ -15,10 +15,11 @@ static int verbose;
static const char daemon_usage[] =
"git-daemon [--verbose] [--syslog] [--inetd | --port=n] [--export-all]\n"
" [--timeout=n] [--init-timeout=n] [directory...]";
" [--timeout=n] [--init-timeout=n] [--strict-paths] [directory...]";
/* List of acceptable pathname prefixes */
static char **ok_paths = NULL;
static int strict_paths = 0;
/* If this is set, git-daemon-export-ok is not required */
static int export_all_trees = 0;
@ -81,69 +82,52 @@ static void loginfo(const char *err, ...)
va_end(params);
}
static int path_ok(const char *dir)
static char *path_ok(char *dir)
{
const char *p = dir;
char **pp;
int sl, ndot;
char *path = enter_repo(dir, strict_paths);
/* The pathname here should be an absolute path. */
if ( *p++ != '/' )
return 0;
sl = 1; ndot = 0;
for (;;) {
if ( *p == '.' ) {
ndot++;
} else if ( *p == '\0' ) {
/* Reject "." and ".." at the end of the path */
if ( sl && ndot > 0 && ndot < 3 )
return 0;
/* Otherwise OK */
break;
} else if ( *p == '/' ) {
/* Refuse "", "." or ".." */
if ( sl && ndot < 3 )
return 0;
sl = 1;
ndot = 0;
} else {
sl = ndot = 0;
}
p++;
if (!path) {
logerror("'%s': unable to chdir or not a git archive", dir);
return NULL;
}
if ( ok_paths && *ok_paths ) {
int ok = 0;
int dirlen = strlen(dir);
char **pp;
int pathlen = strlen(path);
/* The validation is done on the paths after enter_repo
* canonicalization, so whitelist should be written in
* terms of real pathnames (i.e. after ~user is expanded
* and symlinks resolved).
*/
for ( pp = ok_paths ; *pp ; pp++ ) {
int len = strlen(*pp);
if ( len <= dirlen &&
!strncmp(*pp, dir, len) &&
(dir[len] == '/' || dir[len] == '\0') ) {
ok = 1;
break;
}
if (len <= pathlen &&
!memcmp(*pp, path, len) &&
(path[len] == '\0' ||
(!strict_paths && path[len] == '/')))
return path;
}
if ( !ok )
return 0; /* Path not in whitelist */
}
else {
/* be backwards compatible */
if (!strict_paths)
return path;
}
return 1; /* Path acceptable */
logerror("'%s': not in whitelist", path);
return NULL; /* Fallthrough. Deny by default */
}
static int set_dir(const char *dir)
static int upload(char *dir)
{
if (!path_ok(dir)) {
errno = EACCES;
return -1;
}
/* Timeout as string */
char timeout_buf[64];
const char *path;
if ( chdir(dir) )
loginfo("Request for '%s'", dir);
if (!(path = path_ok(dir)))
return -1;
/*
@ -152,45 +136,17 @@ static int set_dir(const char *dir)
* We want a readable HEAD, usable "objects" directory, and
* a "git-daemon-export-ok" flag that says that the other side
* is ok with us doing this.
*
* path_ok() uses enter_repo() and does whitelist checking.
* We only need to make sure the repository is exported.
*/
if (!export_all_trees && access("git-daemon-export-ok", F_OK)) {
logerror("'%s': repository not exported.", path);
errno = EACCES;
return -1;
}
if (access("objects/", X_OK) || access("HEAD", R_OK)) {
errno = EINVAL;
return -1;
}
/* If all this passed, we're OK */
return 0;
}
static int upload(char *dir)
{
/* Try paths in this order */
static const char *paths[] = { "%s", "%s/.git", "%s.git", "%s.git/.git", NULL };
const char **pp;
/* Enough for the longest path above including final null */
int buflen = strlen(dir)+10;
char *dirbuf = xmalloc(buflen);
/* Timeout as string */
char timeout_buf[64];
loginfo("Request for '%s'", dir);
for ( pp = paths ; *pp ; pp++ ) {
snprintf(dirbuf, buflen, *pp, dir);
if ( !set_dir(dirbuf) )
break;
}
if ( !*pp ) {
logerror("Cannot set directory '%s': %s", dir, strerror(errno));
return -1;
}
/*
* We'll ignore SIGTERM from now on, we have a
* good client.
@ -216,7 +172,7 @@ static int execute(void)
if (len && line[len-1] == '\n')
line[--len] = 0;
if (!strncmp("git-upload-pack /", line, 17))
if (!strncmp("git-upload-pack ", line, 16))
return upload(line+16);
logerror("Protocol error: '%s'", line);
@ -510,8 +466,14 @@ static int socksetup(int port, int **socklist_p)
return 0;
}
if (listen(sockfd, 5) < 0) {
close(sockfd);
return 0;
}
*socklist_p = xmalloc(sizeof(int));
**socklist_p = sockfd;
return 1;
}
#endif
@ -594,6 +556,7 @@ int main(int argc, char **argv)
}
if (!strcmp(arg, "--inetd")) {
inetd_mode = 1;
log_syslog = 1;
continue;
}
if (!strcmp(arg, "--verbose")) {
@ -602,7 +565,6 @@ int main(int argc, char **argv)
}
if (!strcmp(arg, "--syslog")) {
log_syslog = 1;
openlog("git-daemon", 0, LOG_DAEMON);
continue;
}
if (!strcmp(arg, "--export-all")) {
@ -611,9 +573,15 @@ int main(int argc, char **argv)
}
if (!strncmp(arg, "--timeout=", 10)) {
timeout = atoi(arg+10);
continue;
}
if (!strncmp(arg, "--init-timeout=", 15)) {
init_timeout = atoi(arg+15);
continue;
}
if (!strcmp(arg, "--strict-paths")) {
strict_paths = 1;
continue;
}
if (!strcmp(arg, "--")) {
ok_paths = &argv[i+1];
@ -626,10 +594,21 @@ int main(int argc, char **argv)
usage(daemon_usage);
}
if (log_syslog)
openlog("git-daemon", 0, LOG_DAEMON);
if (strict_paths && (!ok_paths || !*ok_paths)) {
if (!inetd_mode)
die("git-daemon: option --strict-paths requires a whitelist");
logerror("option --strict-paths requires a whitelist");
exit (1);
}
if (inetd_mode) {
fclose(stderr); //FIXME: workaround
return execute();
} else {
return serve(port);
}
return serve(port);
}

186
date.c
View File

@ -5,6 +5,7 @@
*/
#include <time.h>
#include <sys/time.h>
#include "cache.h"
@ -33,7 +34,7 @@ static const char *month_names[] = {
};
static const char *weekday_names[] = {
"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"
"Sundays", "Mondays", "Tuesdays", "Wednesdays", "Thursdays", "Fridays", "Saturdays"
};
/*
@ -460,3 +461,186 @@ void datestamp(char *buf, int bufsize)
date_string(now, offset, buf, bufsize);
}
static void update_tm(struct tm *tm, unsigned long sec)
{
time_t n = mktime(tm) - sec;
localtime_r(&n, tm);
}
static void date_yesterday(struct tm *tm, int *num)
{
update_tm(tm, 24*60*60);
}
static void date_time(struct tm *tm, int hour)
{
if (tm->tm_hour < hour)
date_yesterday(tm, NULL);
tm->tm_hour = hour;
tm->tm_min = 0;
tm->tm_sec = 0;
}
static void date_midnight(struct tm *tm, int *num)
{
date_time(tm, 0);
}
static void date_noon(struct tm *tm, int *num)
{
date_time(tm, 12);
}
static void date_tea(struct tm *tm, int *num)
{
date_time(tm, 17);
}
static const struct special {
const char *name;
void (*fn)(struct tm *, int *);
} special[] = {
{ "yesterday", date_yesterday },
{ "noon", date_noon },
{ "midnight", date_midnight },
{ "tea", date_tea },
{ NULL }
};
static const char *number_name[] = {
"zero", "one", "two", "three", "four",
"five", "six", "seven", "eight", "nine", "ten",
};
static const struct typelen {
const char *type;
int length;
} typelen[] = {
{ "seconds", 1 },
{ "minutes", 60 },
{ "hours", 60*60 },
{ "days", 24*60*60 },
{ "weeks", 7*24*60*60 },
{ NULL }
};
static const char *approxidate_alpha(const char *date, struct tm *tm, int *num)
{
const struct typelen *tl;
const struct special *s;
const char *end = date;
int n = 1, i;
while (isalpha(*++end))
n++;
for (i = 0; i < 12; i++) {
int match = match_string(date, month_names[i]);
if (match >= 3) {
tm->tm_mon = i;
return end;
}
}
for (s = special; s->name; s++) {
int len = strlen(s->name);
if (match_string(date, s->name) == len) {
s->fn(tm, num);
return end;
}
}
if (!*num) {
for (i = 1; i < 11; i++) {
int len = strlen(number_name[i]);
if (match_string(date, number_name[i]) == len) {
*num = i;
return end;
}
}
if (match_string(date, "last") == 4)
*num = 1;
return end;
}
tl = typelen;
while (tl->type) {
int len = strlen(tl->type);
if (match_string(date, tl->type) >= len-1) {
update_tm(tm, tl->length * *num);
*num = 0;
return end;
}
tl++;
}
for (i = 0; i < 7; i++) {
int match = match_string(date, weekday_names[i]);
if (match >= 3) {
int diff, n = *num -1;
*num = 0;
diff = tm->tm_wday - i;
if (diff <= 0)
n++;
diff += 7*n;
update_tm(tm, diff * 24 * 60 * 60);
return end;
}
}
if (match_string(date, "months") >= 5) {
int n = tm->tm_mon - *num;
*num = 0;
while (n < 0) {
n += 12;
tm->tm_year--;
}
tm->tm_mon = n;
return end;
}
if (match_string(date, "years") >= 4) {
tm->tm_year -= *num;
*num = 0;
return end;
}
return end;
}
unsigned long approxidate(const char *date)
{
int number = 0;
struct tm tm, now;
struct timeval tv;
char buffer[50];
if (parse_date(date, buffer, sizeof(buffer)) > 0)
return strtoul(buffer, NULL, 10);
gettimeofday(&tv, NULL);
localtime_r(&tv.tv_sec, &tm);
now = tm;
for (;;) {
unsigned char c = *date;
if (!c)
break;
date++;
if (isdigit(c)) {
char *end;
number = strtoul(date-1, &end, 10);
date = end;
continue;
}
if (isalpha(c))
date = approxidate_alpha(date-1, &tm, &number);
}
if (number > 0 && number < 32)
tm.tm_mday = number;
if (tm.tm_mon > now.tm_mon)
tm.tm_year--;
return mktime(&tm);
}

69
debian/changelog vendored
View File

@ -1,3 +1,45 @@
git-core (0.99.9k-0) unstable; urgency=low
* GIT 0.99.9k but not 1.0rc yet.
-- Junio C Hamano <junkio@cox.net> Fri, 25 Nov 2005 16:33:11 -0800
git-core (0.99.9j-0) unstable; urgency=low
* GIT 0.99.9j aka 1.0rc3
-- Junio C Hamano <junkio@cox.net> Wed, 16 Nov 2005 20:39:55 -0800
git-core (0.99.9i-0) unstable; urgency=low
* GIT 0.99.9i aka 1.0rc2
-- Junio C Hamano <junkio@cox.net> Mon, 14 Nov 2005 18:38:27 -0800
git-core (0.99.9h-0) unstable; urgency=low
* GIT 0.99.9h
-- Junio C Hamano <junkio@cox.net> Fri, 11 Nov 2005 22:33:18 -0800
git-core (0.99.9g-0) unstable; urgency=low
* GIT 0.99.9g
-- Junio C Hamano <junkio@cox.net> Wed, 9 Nov 2005 21:01:55 -0800
git-core (0.99.9f-0) unstable; urgency=low
* GIT 0.99.9f
-- Junio C Hamano <junkio@cox.net> Tue, 8 Nov 2005 01:21:52 -0800
git-core (0.99.9e-0) unstable; urgency=low
* GIT 0.99.9e
-- Junio C Hamano <junkio@cox.net> Sun, 6 Nov 2005 18:37:18 -0800
git-core (0.99.9d-0) unstable; urgency=low
* GIT 0.99.9d
@ -22,6 +64,33 @@ git-core (0.99.9a-0) unstable; urgency=low
-- Junio C Hamano <junkio@cox.net> Sun, 30 Oct 2005 15:03:32 -0800
git-core (0.99.9.GIT-2) unstable; urgency=low
* Build Dependency did not include libexpat-dev.
-- Junio C Hamano <junkio@cox.net> Sun, 13 Nov 2005 01:55:34 -0800
git-core (0.99.9.GIT-1) unstable; urgency=low
* Do not scatter txt and html documentation into feature
subpackages. Do place man pages into them.
* Capture more cvs stuff into git-cvs package.
-- Junio C Hamano <junkio@cox.net> Tue, 8 Nov 2005 01:19:06 -0800
git-core (0.99.9.GIT-0) unstable; urgency=low
* Test Build.
-- Junio C Hamano <junkio@cox.net> Sat, 5 Nov 2005 11:18:13 -0800
git-core (0.99.9-1) unstable; urgency=low
* Split the git-core binary package into core, doc, and foreign SCM
interoperability modules.
-- Junio C Hamano <junkio@cox.net> Sat, 5 Nov 2005 11:18:13 -0800
git-core (0.99.9-0) unstable; urgency=low
* GIT 0.99.9

41
debian/control vendored
View File

@ -2,13 +2,13 @@ Source: git-core
Section: devel
Priority: optional
Maintainer: Junio C Hamano <junkio@cox.net>
Build-Depends-Indep: libz-dev, libssl-dev, libcurl3-dev|libcurl3-gnutls-dev|libcurl3-openssl-dev, asciidoc (>= 6.0.3), xmlto, debhelper (>= 4.0.0), bc
Build-Depends-Indep: libz-dev, libssl-dev, libcurl3-dev|libcurl3-gnutls-dev|libcurl3-openssl-dev, asciidoc (>= 7), xmlto, debhelper (>= 4.0.0), bc, libexpat-dev
Standards-Version: 3.6.1
Package: git-core
Architecture: any
Depends: ${shlibs:Depends}, ${perl:Depends}, ${misc:Depends}, rcs
Recommends: rsync, curl, ssh, libmail-sendmail-perl, libemail-valid-perl, libsvn-core-perl (>= 1.2.1), python (>= 2.4.0), less
Recommends: rsync, curl, ssh, python (>= 2.4.0), less
Suggests: cogito, patch
Conflicts: git, cogito (<< 0.13)
Description: The git content addressable filesystem
@ -18,9 +18,46 @@ Description: The git content addressable filesystem
enables human beings to work with the database in a manner to a degree
similar to other SCM tools.
Package: git-doc
Architecture: all
Depends: ${shlibs:Depends}, ${misc:Depends}, git-core
Description: The git content addressable filesystem, Documentation
This package contains documentation for GIT.
Package: git-tk
Architecture: all
Depends: ${shlibs:Depends}, ${misc:Depends}, git-core, tk8.4
Description: The git content addressable filesystem, GUI add-on
This package contains 'gitk', the git revision tree visualizer.
Package: git-svn
Architecture: all
Depends: ${shlibs:Depends}, ${misc:Depends}, ${perl:Depends}, git-core, libsvn-core-perl (>= 1.2.1)
Suggests: subversion
Description: The git content addressable filesystem, SVN interoperability
This package contains 'git-svnimport', to import development history from
SVN repositories.
Package: git-arch
Architecture: all
Depends: ${shlibs:Depends}, ${misc:Depends}, ${perl:Depends}, git-core
Suggests: tla, bazaar
Description: The git content addressable filesystem, GNUArch interoperability
This package contains 'git-archimport', to import development history from
GNUArch repositories.
Package: git-cvs
Architecture: all
Depends: ${shlibs:Depends}, ${misc:Depends}, ${perl:Depends}, git-core, cvsps (>= 2.1)
Suggests: cvs
Description: The git content addressable filesystem, CVS interoperability
This package contains 'git-cvsimport', to import development history from
CVS repositories.
Package: git-email
Architecture: all
Depends: ${shlibs:Depends}, ${misc:Depends}, git-core, libmail-sendmail-perl, libemail-valid-perl
Description: The git content addressable filesystem, e-mail add-on
This package contains 'git-send-email', to send a series of patch e-mails.

2
debian/git-arch.files vendored Normal file
View File

@ -0,0 +1,2 @@
/usr/bin/git-arch*
/usr/share/man/*/git-arch*

View File

@ -6,6 +6,8 @@ Section: Devel
Format: HTML
Index: /usr/share/doc/git-core/git.html
Files: /usr/share/doc/git-core/*.html
/usr/share/doc/git-core/*/*.html
Format: text
Files: /usr/share/doc/git-core/git.txt*
Files: /usr/share/doc/git-core/*.txt
/usr/share/doc/git-core/*/*.txt

2
debian/git-cvs.files vendored Normal file
View File

@ -0,0 +1,2 @@
/usr/bin/git-cvs*
/usr/share/man/*/git-cvs*

4
debian/git-doc.files vendored Normal file
View File

@ -0,0 +1,4 @@
/usr/share/doc/git-core/*.txt
/usr/share/doc/git-core/*.html
/usr/share/doc/git-core/*/*.html
/usr/share/doc/git-core/*/*.txt

2
debian/git-email.files vendored Normal file
View File

@ -0,0 +1,2 @@
/usr/bin/git-send-email
/usr/share/man/*/git-send-email.*

2
debian/git-svn.files vendored Normal file
View File

@ -0,0 +1,2 @@
/usr/bin/git-svn*
/usr/share/man/*/git-svn*

1
debian/git-tk.files vendored
View File

@ -1,3 +1,2 @@
/usr/bin/gitk
/usr/share/man/man1/gitk.*
/usr/share/doc/git-core/gitk.*

11
debian/rules vendored
View File

@ -41,7 +41,7 @@ MAN_DESTDIR := $(DESTDIR)/$(MANDIR)
build: debian/build-stamp
debian/build-stamp:
dh_testdir
$(MAKE) prefix=$(PREFIX) PYTHON_PATH=/usr/bin/python2.4 all doc test
$(MAKE) prefix=$(PREFIX) PYTHON_PATH=/usr/bin/python2.4 all test doc
touch debian/build-stamp
debian-clean:
@ -62,10 +62,15 @@ install: build
make DESTDIR=$(DESTDIR) prefix=$(PREFIX) mandir=$(MANDIR) \
install install-doc
mkdir -p $(DOC_DESTDIR)
find $(DOC) '(' -name '*.txt' -o -name '*.html' ')' -exec install {} $(DOC_DESTDIR) ';'
make -C Documentation DESTDIR=$(DESTDIR) prefix=$(PREFIX) \
WEBDOC_DEST=$(DOC_DESTDIR) install-webdoc
dh_movefiles -p git-arch
dh_movefiles -p git-cvs
dh_movefiles -p git-svn
dh_movefiles -p git-tk
dh_movefiles -p git-email
dh_movefiles -p git-doc
dh_movefiles -p git-core
find debian/tmp -type d -o -print | sed -e 's/^/? /'

View File

@ -38,7 +38,7 @@ int main(int argc, const char **argv)
const char *prefix = setup_git_directory();
int entries, i;
git_config(git_default_config);
git_config(git_diff_config);
diff_setup(&diff_options);
while (1 < argc && argv[1][0] == '-') {
if (!strcmp(argv[1], "--")) {

View File

@ -180,7 +180,7 @@ int main(int argc, const char **argv)
int allow_options = 1;
int i;
git_config(git_default_config);
git_config(git_diff_config);
diff_setup(&diff_options);
for (i = 1; i < argc; i++) {
const char *arg = argv[i];

View File

@ -55,6 +55,9 @@ int main(int ac, const char **av)
{
int stage1, stage2;
setup_git_directory();
git_config(git_diff_config);
read_cache();
diff_setup(&diff_options);
while (1 < ac && av[1][0] == '-') {

View File

@ -3,6 +3,7 @@
#include "commit.h"
static int show_root_diff = 0;
static int no_commit_id = 0;
static int verbose_header = 0;
static int ignore_merges = 1;
static int read_stdin = 0;
@ -29,7 +30,8 @@ static int call_diff_flush(void)
return 0;
}
if (header) {
printf("%s%c", header, diff_options.line_termination);
if (!no_commit_id)
printf("%s%c", header, diff_options.line_termination);
header = NULL;
}
diff_flush(&diff_options);
@ -67,52 +69,50 @@ static int diff_root_tree(const unsigned char *new, const char *base)
return retval;
}
static const char *generate_header(const char *commit, const char *parent, const char *msg, unsigned long len)
static const char *generate_header(const char *commit, const char *parent, const char *msg)
{
static char this_header[16384];
int offset;
unsigned long len;
if (!verbose_header)
return commit;
len = strlen(msg);
offset = sprintf(this_header, "%s%s (from %s)\n", header_prefix, commit, parent);
offset += pretty_print_commit(commit_format, msg, len, this_header + offset, sizeof(this_header) - offset);
return this_header;
}
static int diff_tree_commit(const unsigned char *commit, const char *name)
static int diff_tree_commit(const unsigned char *commit_sha1)
{
unsigned long size, offset;
char *buf = read_object_with_reference(commit, "commit", &size, NULL);
struct commit *commit;
struct commit_list *parents;
char name[50];
unsigned char sha1[20];
if (!buf)
sprintf(name, "%s^0", sha1_to_hex(commit_sha1));
if (get_sha1(name, sha1))
return -1;
if (!name) {
static char commit_name[60];
strcpy(commit_name, sha1_to_hex(commit));
name = commit_name;
}
name[40] = 0;
commit = lookup_commit(sha1);
/* Root commit? */
if (show_root_diff && memcmp(buf + 46, "parent ", 7)) {
header = generate_header(name, "root", buf, size);
diff_root_tree(commit, "");
if (show_root_diff && !commit->parents) {
header = generate_header(name, "root", commit->buffer);
diff_root_tree(commit_sha1, "");
}
/* More than one parent? */
if (ignore_merges) {
if (!memcmp(buf + 46 + 48, "parent ", 7))
if (ignore_merges && commit->parents && commit->parents->next)
return 0;
}
offset = 46;
while (offset + 48 < size && !memcmp(buf + offset, "parent ", 7)) {
unsigned char parent[20];
if (get_sha1_hex(buf + offset + 7, parent))
return -1;
header = generate_header(name, sha1_to_hex(parent), buf, size);
diff_tree_sha1_top(parent, commit, "");
for (parents = commit->parents; parents; parents = parents->next) {
struct commit *parent = parents->item;
header = generate_header(name,
sha1_to_hex(parent->object.sha1),
commit->buffer);
diff_tree_sha1_top(parent->object.sha1, commit_sha1, "");
if (!header && verbose_header) {
header_prefix = "\ndiff-tree ";
/*
@ -120,9 +120,7 @@ static int diff_tree_commit(const unsigned char *commit, const char *name)
* don't print the diffs.
*/
}
offset += 48;
}
free(buf);
return 0;
}
@ -145,7 +143,7 @@ static int diff_tree_stdin(char *line)
return diff_tree_sha1_top(parent, commit, "");
}
line[40] = 0;
return diff_tree_commit(commit, line);
return diff_tree_commit(commit);
}
static const char diff_tree_usage[] =
@ -162,7 +160,7 @@ int main(int argc, const char **argv)
unsigned char sha1[2][20];
const char *prefix = setup_git_directory();
git_config(git_default_config);
git_config(git_diff_config);
nr_sha1 = 0;
diff_setup(&diff_options);
@ -231,6 +229,10 @@ int main(int argc, const char **argv)
show_root_diff = 1;
continue;
}
if (!strcmp(arg, "--no-commit-id")) {
no_commit_id = 1;
continue;
}
usage(diff_tree_usage);
}
if (diff_options.output_format == DIFF_FORMAT_PATCH)
@ -244,7 +246,7 @@ int main(int argc, const char **argv)
usage(diff_tree_usage);
break;
case 1:
diff_tree_commit(sha1[0], NULL);
diff_tree_commit(sha1[0]);
break;
case 2:
diff_tree_sha1_top(sha1[0], sha1[1], "");

62
diff.c
View File

@ -13,6 +13,18 @@ static const char *diff_opts = "-pu";
static int use_size_cache;
int diff_rename_limit_default = -1;
int git_diff_config(const char *var, const char *value)
{
if (!strcmp(var, "diff.renamelimit")) {
diff_rename_limit_default = git_config_int(var, value);
return 0;
}
return git_default_config(var, value);
}
static char *quote_one(const char *str)
{
int needlen;
@ -648,7 +660,7 @@ static void diff_fill_sha1_info(struct diff_filespec *one)
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();
char msg[PATH_MAX*2+300], *xfrm_msg;
@ -711,11 +723,11 @@ static void run_diff(struct diff_filepair *p)
if (memcmp(one->sha1, two->sha1, 20)) {
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);
len += snprintf(msg + len, sizeof(msg) - len,
"index %.7s..%.7s", one_sha1,
sha1_to_hex(two->sha1));
index_fmt, one_sha1, sha1_to_hex(two->sha1));
if (one->mode == two->mode)
len += snprintf(msg + len, sizeof(msg) - len,
" %06o", one->mode);
@ -761,9 +773,12 @@ void diff_setup(struct diff_options *options)
int diff_setup_done(struct diff_options *options)
{
if ((options->find_copies_harder || 0 <= options->rename_limit) &&
options->detect_rename != DIFF_DETECT_COPY)
if ((options->find_copies_harder &&
options->detect_rename != DIFF_DETECT_COPY) ||
(0 <= options->rename_limit && !options->detect_rename))
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 (!active_cache)
/* read-cache does not die even when it fails
@ -789,6 +804,8 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac)
options->line_termination = 0;
else if (!strncmp(arg, "-l", 2))
options->rename_limit = strtoul(arg+2, NULL, 10);
else if (!strcmp(arg, "--full-index"))
options->full_index = 1;
else if (!strcmp(arg, "--name-only"))
options->output_format = DIFF_FORMAT_NAME;
else if (!strcmp(arg, "--name-status"))
@ -831,16 +848,29 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac)
static int parse_num(const char **cp_p)
{
int num, scale, ch, cnt;
unsigned long num, scale;
int ch, dot;
const char *cp = *cp_p;
cnt = num = 0;
num = 0;
scale = 1;
while ('0' <= (ch = *cp) && ch <= '9') {
if (cnt++ < 5) {
/* We simply ignore more than 5 digits precision. */
scale *= 10;
num = num * 10 + ch - '0';
dot = 0;
for(;;) {
ch = *cp;
if ( !dot && ch == '.' ) {
scale = 1;
dot = 1;
} else if ( ch == '%' ) {
scale = dot ? scale*100 : 100;
cp++; /* % is always at the end */
break;
} else if ( ch >= '0' && ch <= '9' ) {
if ( scale < 100000 ) {
scale *= 10;
num = (num*10) + (ch-'0');
}
} else {
break;
}
cp++;
}
@ -849,7 +879,7 @@ static int parse_num(const char **cp_p)
/* user says num divided by scale and we say internally that
* is MAX_SCORE * num / scale.
*/
return (MAX_SCORE * num / scale);
return (num >= scale) ? MAX_SCORE : (MAX_SCORE * num / scale);
}
int diff_scoreopt_parse(const char *opt)
@ -1017,7 +1047,7 @@ int diff_unmodified_pair(struct diff_filepair *p)
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))
return;
@ -1026,7 +1056,7 @@ static void diff_flush_patch(struct diff_filepair *p)
(DIFF_FILE_VALID(p->two) && S_ISDIR(p->two->mode)))
return; /* no tree diffs in patch format */
run_diff(p);
run_diff(p, o);
}
int diff_queue_is_empty(void)
@ -1158,7 +1188,7 @@ void diff_flush(struct diff_options *options)
die("internal error in diff-resolve-rename-copy");
switch (diff_output_format) {
case DIFF_FORMAT_PATCH:
diff_flush_patch(p);
diff_flush_patch(p, options);
break;
case DIFF_FORMAT_RAW:
case DIFF_FORMAT_NAME_STATUS:

5
diff.h
View File

@ -32,7 +32,8 @@ struct diff_options {
const char *orderfile;
const char *pickaxe;
unsigned recursive:1,
tree_in_recursive:1;
tree_in_recursive:1,
full_index:1;
int break_opt;
int detect_rename;
int find_copies_harder;
@ -76,6 +77,7 @@ extern int diff_scoreopt_parse(const char *opt);
#define DIFF_SETUP_USE_CACHE 2
#define DIFF_SETUP_USE_SIZE_CACHE 4
extern int git_diff_config(const char *var, const char *value);
extern void diff_setup(struct diff_options *);
extern int diff_opt_parse(struct diff_options *, const char **, int);
extern int diff_setup_done(struct diff_options *);
@ -96,6 +98,7 @@ extern void diffcore_std_no_resolve(struct diff_options *);
" -u synonym for -p.\n" \
" --name-only show only names 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" \
" -B detect complete rewrites.\n" \
" -M detect renames.\n" \

View File

@ -283,7 +283,7 @@ void diffcore_rename(struct diff_options *options)
register_rename_src(p->one, 1);
}
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 */
/* We really want to cull the candidates list early
@ -307,6 +307,9 @@ void diffcore_rename(struct diff_options *options)
if (rename_count == rename_dst_nr)
goto cleanup;
if (minimum_score == MAX_SCORE)
goto cleanup;
num_create = (rename_dst_nr - rename_count);
num_src = rename_src_nr;
mx = xmalloc(sizeof(*mx) * num_create * num_src);

View File

@ -12,6 +12,7 @@
char git_default_email[MAX_GITNAME];
char git_default_name[MAX_GITNAME];
int trust_executable_bit = 1;
int only_use_symrefs = 0;
static char *git_dir, *git_object_dir, *git_index_file, *git_refs_dir,
*git_graft_file;

View File

@ -458,5 +458,19 @@ int main(int argc, char **argv)
close(fd[0]);
close(fd[1]);
finish_connect(pid);
if (!ret && nr_heads) {
/* If the heads to pull were given, we should have
* consumed all of them by matching the remote.
* Otherwise, 'git-fetch remote no-such-ref' would
* silently succeed without issuing an error.
*/
for (i = 0; i < nr_heads; i++)
if (heads[i] && heads[i][0]) {
error("no such remote ref %s", heads[i]);
ret = 1;
}
}
return ret;
}

View File

@ -56,7 +56,6 @@ static void check_connectivity(void)
/* Look up all the requirements, warn about missing objects.. */
for (i = 0; i < nr_objs; i++) {
struct object *obj = objs[i];
struct object_list *refs;
if (!obj->parsed) {
if (!standalone && has_sha1_file(obj->sha1))
@ -67,14 +66,19 @@ static void check_connectivity(void)
continue;
}
for (refs = obj->refs; refs; refs = refs->next) {
if (refs->item->parsed ||
(!standalone && has_sha1_file(refs->item->sha1)))
continue;
printf("broken link from %7s %s\n",
obj->type, sha1_to_hex(obj->sha1));
printf(" to %7s %s\n",
refs->item->type, sha1_to_hex(refs->item->sha1));
if (obj->refs) {
const struct object_refs *refs = obj->refs;
unsigned j;
for (j = 0; j < refs->count; j++) {
struct object *ref = refs->ref[j];
if (ref->parsed ||
(!standalone && has_sha1_file(ref->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)) {
@ -184,10 +188,17 @@ static int fsck_tree(struct tree *item)
default:
break;
}
free(last->name);
free(last);
}
last = entry;
}
if (last) {
free(last->name);
free(last);
}
item->entries = NULL;
retval = 0;
if (has_full_path) {

112
git-am.sh
View File

@ -1,18 +1,12 @@
#!/bin/sh
#
#
. 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
. git-sh-setup
usage () {
echo >&2 "usage: $0 [--signoff] [--dotest=<dir>] [--utf8] [--3way] <mbox>"
echo >&2 "usage: $0 [--signoff] [--dotest=<dir>] [--utf8] [--binary] [--3way] <mbox>"
echo >&2 " or, when resuming"
echo >&2 " $0 [--skip]"
echo >&2 " $0 [--skip | --resolved]"
exit 1;
}
@ -46,7 +40,7 @@ fall_back_3way () {
cd "$dotest/patch-merge-tmp-dir" &&
GIT_INDEX_FILE="../patch-merge-tmp-index" \
GIT_OBJECT_DIRECTORY="$O_OBJECT" \
git-apply --index <../patch
git-apply $binary --index <../patch
)
then
echo Using index info to reconstruct a base tree...
@ -77,7 +71,7 @@ fall_back_3way () {
GIT_OBJECT_DIRECTORY="$O_OBJECT" &&
export GIT_INDEX_FILE GIT_OBJECT_DIRECTORY &&
git-read-tree "$base" &&
git-apply --index &&
git-apply $binary --index &&
mv ../patch-merge-tmp-index ../patch-merge-index &&
echo "$base" >../patch-merge-base
) <"$dotest/patch" 2>/dev/null && break
@ -104,7 +98,7 @@ fall_back_3way () {
}
prec=4
dotest=.dotest sign= utf8= keep= skip= interactive=
dotest=.dotest sign= utf8= keep= skip= interactive= resolved= binary=
while case "$#" in 0) break;; esac
do
@ -119,6 +113,9 @@ do
--interacti|--interactiv|--interactive)
interactive=t; shift ;;
-b|--b|--bi|--bin|--bina|--binar|--binary)
binary=t; shift ;;
-3|--3|--3w|--3wa|--3way)
threeway=t; shift ;;
-s|--s|--si|--sig|--sign|--signo|--signof|--signoff)
@ -128,6 +125,9 @@ do
-k|--k|--ke|--kee|--keep)
keep=t; shift ;;
-r|--r|--re|--res|--reso|--resol|--resolv|--resolve|--resolved)
resolved=t; shift ;;
--sk|--ski|--skip)
skip=t; shift ;;
@ -140,6 +140,8 @@ do
esac
done
# If the dotest directory exists, but we have finished applying all the
# patches in them, clear it out.
if test -d "$dotest" &&
last=$(cat "$dotest/last") &&
next=$(cat "$dotest/next") &&
@ -155,9 +157,9 @@ then
die "previous dotest directory $dotest still exists but mbox given."
resume=yes
else
# Make sure we are not given --skip
test ",$skip," = ,, ||
die "we are not resuming."
# Make sure we are not given --skip nor --resolved
test ",$skip,$resolved," = ,,, ||
die "we are not resuming."
# Start afresh.
mkdir -p "$dotest" || exit
@ -170,12 +172,29 @@ else
exit 1
}
# -b, -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 "$binary" >"$dotest/binary"
echo "$sign" >"$dotest/sign"
echo "$utf8" >"$dotest/utf8"
echo "$keep" >"$dotest/keep"
echo 1 >"$dotest/next"
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/binary")" = t
then
binary=--allow-binary-replacement
fi
if test "$(cat "$dotest/utf8")" = t
then
utf8=-u
@ -216,6 +235,15 @@ do
go_next
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
'')
git-mailinfo $keep $utf8 "$dotest/msg" "$dotest/patch" \
@ -224,29 +252,33 @@ do
git-stripspace < "$dotest/msg" > "$dotest/msg-clean"
;;
esac
resume=
GIT_AUTHOR_NAME="$(sed -n '/^Author/ s/Author: //p' "$dotest/info")"
GIT_AUTHOR_EMAIL="$(sed -n '/^Email/ s/Email: //p' "$dotest/info")"
GIT_AUTHOR_DATE="$(sed -n '/^Date/ s/Date: //p' "$dotest/info")"
SUBJECT="$(sed -n '/^Subject/ s/Subject: //p' "$dotest/info")"
export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_AUTHOR_DATE
SUBJECT="$(sed -n '/^Subject/ s/Subject: //p' "$dotest/info")"
case "$keep_subject" in -k) SUBJECT="[PATCH] $SUBJECT" ;; esac
if test '' != "$SIGNOFF"
then
case "$resume" in
'')
if test '' != "$SIGNOFF"
then
LAST_SIGNED_OFF_BY=`
sed -ne '/^Signed-off-by: /p' "$dotest/msg-clean" |
tail -n 1
sed -ne '/^Signed-off-by: /p' \
"$dotest/msg-clean" |
tail -n 1
`
ADD_SIGNOFF=$(test "$LAST_SIGNED_OFF_BY" = "$SIGNOFF" || {
ADD_SIGNOFF=`
test "$LAST_SIGNED_OFF_BY" = "$SIGNOFF" || {
test '' = "$LAST_SIGNED_OFF_BY" && echo
echo "$SIGNOFF"
})
else
}`
else
ADD_SIGNOFF=
fi
{
fi
{
echo "$SUBJECT"
if test -s "$dotest/msg-clean"
then
@ -257,8 +289,18 @@ do
then
echo "$ADD_SIGNOFF"
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
resume=
if test "$interactive" = t
then
test -t 0 ||
@ -303,7 +345,21 @@ do
echo "Applying '$SUBJECT'"
echo
git-apply --index "$dotest/patch"; apply_status=$?
case "$resolved" in
'')
git-apply $binary --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
then
if (fall_back_3way)

View File

@ -18,7 +18,7 @@
##
## git-am is supposed to be the newer and better tool for this job.
. git-sh-setup || die "Not a git archive"
. git-sh-setup
usage () {
echo >&2 "applymbox [-u] [-k] [-q] [-m] (-c .dotest/<num> | mbox) [signoff]"

View File

@ -10,7 +10,7 @@
## $3 - "info" file with Author, email and subject
## $4 - optional file containing signoff to add
##
. git-sh-setup || die "Not a git archive."
. git-sh-setup
final=.dotest/final-commit
##

View File

@ -30,6 +30,24 @@ See man (1) git-archimport for more details.
Add print in front of the shell commands invoked via backticks.
=head1 Devel Notes
There are several places where Arch and git terminology are intermixed
and potentially confused.
The notion of a "branch" in git is approximately equivalent to
a "archive/category--branch--version" in Arch. Also, it should be noted
that the "--branch" portion of "archive/category--branch--version" is really
optional in Arch although not many people (nor tools!) seem to know this.
This means that "archive/category--version" is also a valid "branch"
in git terms.
We always refer to Arch names by their fully qualified variant (which
means the "archive" name is prefixed.
For people unfamiliar with Arch, an "archive" is the term for "repository",
and can contain multiple, unrelated branches.
=cut
use strict;
@ -52,14 +70,14 @@ $ENV{'TZ'}="UTC";
my $git_dir = $ENV{"GIT_DIR"} || ".git";
$ENV{"GIT_DIR"} = $git_dir;
my $ptag_dir = "$git_dir/archimport/tags";
our($opt_h,$opt_v, $opt_T,
$opt_C,$opt_t);
our($opt_h,$opt_v, $opt_T,$opt_t,$opt_o);
sub usage() {
print STDERR <<END;
Usage: ${\basename $0} # fetch/update GIT from Arch
[ -h ] [ -v ] [ -T ] [ -t tempdir ]
[ -o ] [ -h ] [ -v ] [ -T ] [ -t tempdir ]
repository/arch-branch [ repository/arch-branch] ...
END
exit(1);
@ -195,25 +213,68 @@ unless (-d $git_dir) { # initial import
opendir(DIR, "$git_dir/archimport/tags")
|| die "can't opendir: $!";
while (my $file = readdir(DIR)) {
# skip non-interesting-files
next unless -f "$git_dir/archimport/tags/$file";
next if $file =~ m/--base-0$/; # don't care for base-0
# skip non-interesting-files
next unless -f "$ptag_dir/$file";
# convert first '--' to '/' from old git-archimport to use
# as an archivename/c--b--v private tag
if ($file !~ m!,!) {
my $oldfile = $file;
$file =~ s!--!,!;
print STDERR "converting old tag $oldfile to $file\n";
rename("$ptag_dir/$oldfile", "$ptag_dir/$file") or die $!;
}
my $sha = ptag($file);
chomp $sha;
# reconvert the 3rd '--' sequence from the end
# into a slash
# $file = reverse $file;
# $file =~ s!^(.+?--.+?--.+?--.+?)--(.+)$!$1/$2!;
# $file = reverse $file;
$rptags{$sha} = $file;
}
closedir DIR;
}
# process patchsets
foreach my $ps (@psets) {
# extract the Arch repository name (Arch "archive" in Arch-speak)
sub extract_reponame {
my $fq_cvbr = shift; # archivename/[[[[category]branch]version]revision]
return (split(/\//, $fq_cvbr))[0];
}
sub extract_versionname {
my $name = shift;
$name =~ s/--(?:patch|version(?:fix)?|base)-\d+$//;
return $name;
}
$ps->{branch} = branchname($ps->{id});
# convert a fully-qualified revision or version to a unique dirname:
# normalperson@yhbt.net-05/mpd--uclinux--1--patch-2
# becomes: normalperson@yhbt.net-05,mpd--uclinux--1
#
# the git notion of a branch is closer to
# archive/category--branch--version than archive/category--branch, so we
# use this to convert to git branch names.
# Also, keep archive names but replace '/' with ',' since it won't require
# subdirectories, and is safer than swapping '--' which could confuse
# reverse-mapping when dealing with bastard branches that
# are just archive/category--version (no --branch)
sub tree_dirname {
my $revision = shift;
my $name = extract_versionname($revision);
$name =~ s#/#,#;
return $name;
}
# old versions of git-archimport just use the <category--branch> part:
sub old_style_branchname {
my $id = shift;
my $ret = safe_pipe_capture($TLA,'parse-package-name','-p',$id);
chomp $ret;
return $ret;
}
*git_branchname = $opt_o ? *old_style_branchname : *tree_dirname;
# process patchsets
foreach my $ps (@psets) {
$ps->{branch} = git_branchname($ps->{id});
#
# ensure we have a clean state
@ -410,8 +471,7 @@ foreach my $ps (@psets) {
open HEAD, ">$git_dir/refs/heads/$ps->{branch}";
print HEAD $commitid;
close HEAD;
unlink ("$git_dir/HEAD");
symlink("refs/heads/$ps->{branch}","$git_dir/HEAD");
system('git-update-ref', 'HEAD', "$ps->{branch}");
# tag accordingly
ptag($ps->{id}, $commitid); # private tag
@ -425,16 +485,9 @@ foreach my $ps (@psets) {
$opt_v && print " + parents: $par \n";
}
sub branchname {
my $id = shift;
$id =~ s#^.+?/##;
my @parts = split(m/--/, $id);
return join('--', @parts[0..1]);
}
sub apply_import {
my $ps = shift;
my $bname = branchname($ps->{id});
my $bname = git_branchname($ps->{id});
`mkdir -p $tmp`;
@ -565,6 +618,11 @@ sub parselog {
next if $t =~ m!\{arch\}/!;
next if $t =~ m!\.arch-ids/!;
next if $t =~ m!\.arch-inventory$!;
# tla cat-archive-log will give us filenames with spaces as file\(sp)name - why?
# we can assume that any filename with \ indicates some pika escaping that we want to get rid of.
if ($t =~ /\\/ ){
$t = `tla escape --unescaped '$t'`;
}
push (@tmp, shell_quote($t));
}
@$ref = @tmp;
@ -577,19 +635,24 @@ sub parselog {
# write/read a tag
sub tag {
my ($tag, $commit) = @_;
$tag =~ s|/|--|g;
$tag = shell_quote($tag);
if ($opt_o) {
$tag =~ s|/|--|g;
} else {
# don't use subdirs for tags yet, it could screw up other porcelains
$tag =~ s|/|,|g;
}
if ($commit) {
open(C,">$git_dir/refs/tags/$tag")
open(C,">","$git_dir/refs/tags/$tag")
or die "Cannot create tag $tag: $!\n";
print C "$commit\n"
or die "Cannot write tag $tag: $!\n";
close(C)
or die "Cannot write tag $tag: $!\n";
print " * Created tag ' $tag' on '$commit'\n" if $opt_v;
print " * Created tag '$tag' on '$commit'\n" if $opt_v;
} else { # read
open(C,"<$git_dir/refs/tags/$tag")
open(C,"<","$git_dir/refs/tags/$tag")
or die "Cannot read tag $tag: $!\n";
$commit = <C>;
chomp $commit;
@ -604,15 +667,16 @@ sub tag {
# reads fail softly if the tag isn't there
sub ptag {
my ($tag, $commit) = @_;
$tag =~ s|/|--|g;
$tag = shell_quote($tag);
# don't use subdirs for tags yet, it could screw up other porcelains
$tag =~ s|/|,|g;
unless (-d "$git_dir/archimport/tags") {
mkpath("$git_dir/archimport/tags");
}
my $tag_file = "$ptag_dir/$tag";
my $tag_branch_dir = dirname($tag_file);
mkpath($tag_branch_dir) unless (-d $tag_branch_dir);
if ($commit) { # write
open(C,">$git_dir/archimport/tags/$tag")
open(C,">",$tag_file)
or die "Cannot create tag $tag: $!\n";
print C "$commit\n"
or die "Cannot write tag $tag: $!\n";
@ -622,10 +686,10 @@ sub ptag {
unless $tag =~ m/--base-0$/;
} else { # read
# if the tag isn't there, return 0
unless ( -s "$git_dir/archimport/tags/$tag") {
unless ( -s $tag_file) {
return 0;
}
open(C,"<$git_dir/archimport/tags/$tag")
open(C,"<",$tag_file)
or die "Cannot read tag $tag: $!\n";
$commit = <C>;
chomp $commit;
@ -658,7 +722,7 @@ sub find_parents {
# simple loop to split the merges
# per branch
foreach my $merge (@{$ps->{merges}}) {
my $branch = branchname($merge);
my $branch = git_branchname($merge);
unless (defined $branches{$branch} ){
$branches{$branch} = [];
}
@ -682,7 +746,13 @@ sub find_parents {
next unless -e "$git_dir/refs/heads/$branch";
my $mergebase = `git-merge-base $branch $ps->{branch}`;
die "Cannot find merge base for $branch and $ps->{branch}" if $?;
if ($?) {
# Don't die here, Arch supports one-way cherry-picking
# between branches with no common base (or any relationship
# at all beforehand)
warn "Cannot find merge base for $branch and $ps->{branch}";
next;
}
chomp $mergebase;
# now walk up to the mergepoint collecting what patches we have
@ -775,12 +845,7 @@ sub commitid2pset {
chomp $commitid;
my $name = $rptags{$commitid}
|| die "Cannot find reverse tag mapping for $commitid";
# the keys in %rptag are slightly munged; unmunge
# reconvert the 3rd '--' sequence from the end
# into a slash
$name = reverse $name;
$name =~ s!^(.+?--.+?--.+?--.+?)--(.+)$!$1/$2!;
$name = reverse $name;
$name =~ s|,|/|;
my $ps = $psets{$name}
|| (print Dumper(sort keys %psets)) && die "Cannot find patchset for $name";
return $ps;

View File

@ -1,5 +1,5 @@
#!/bin/sh
. git-sh-setup || dir "Not a git archive"
. git-sh-setup
usage() {
echo >&2 'usage: git bisect [start|bad|good|next|reset|visualize]

View File

@ -1,9 +1,9 @@
#!/bin/sh
. git-sh-setup || die "Not a git archive"
. git-sh-setup
usage () {
echo >&2 "usage: $(basename $0)"' [-d <branch>] | [<branch> [start-point]]
echo >&2 "usage: $(basename $0)"' [-d <branch>] | [[-f] <branch> [start-point]]
If no arguments, show available branches and mark current branch with a star.
If one argument, create a new branch <branchname> based off of current HEAD.
@ -12,11 +12,12 @@ If two arguments, create a new branch <branchname> based off of <start-point>.
exit 1
}
headref=$(GIT_DIR="$GIT_DIR" git-symbolic-ref HEAD |
sed -e 's|^refs/heads/||')
delete_branch () {
option="$1"
shift
headref=$(GIT_DIR="$GIT_DIR" git-symbolic-ref HEAD |
sed -e 's|^refs/heads/||')
for branch_name
do
case ",$headref," in
@ -52,6 +53,7 @@ delete_branch () {
exit 0
}
force=
while case "$#,$1" in 0,*) break ;; *,-*) ;; *) break ;; esac
do
case "$1" in
@ -59,6 +61,9 @@ do
delete_branch "$@"
exit
;;
-f)
force="$1"
;;
--)
shift
break
@ -72,8 +77,6 @@ done
case "$#" in
0)
headref=$(GIT_DIR="$GIT_DIR" git-symbolic-ref HEAD |
sed -e 's|^refs/heads/||')
git-rev-parse --symbolic --all |
sed -ne 's|^refs/heads/||p' |
sort |
@ -97,11 +100,18 @@ branchname="$1"
rev=$(git-rev-parse --verify "$head") || exit
[ -e "$GIT_DIR/refs/heads/$branchname" ] &&
die "$branchname already exists."
git-check-ref-format "heads/$branchname" ||
die "we do not like '$branchname' as a branch name."
leading=`expr "refs/heads/$branchname" : '\(.*\)/'` &&
mkdir -p "$GIT_DIR/$leading" &&
echo $rev > "$GIT_DIR/refs/heads/$branchname"
if [ -e "$GIT_DIR/refs/heads/$branchname" ]
then
if test '' = "$force"
then
die "$branchname already exists."
elif test "$branchname" = "$headref"
then
die "cannot force-update the current branch."
fi
fi
git update-ref "refs/heads/$branchname" $rev

View File

@ -1,5 +1,5 @@
#!/bin/sh
. git-sh-setup || die "Not a git archive"
. git-sh-setup
usage () {
die "usage: git checkout [-f] [-b <new_branch>] [<branch>] [<paths>...]"
@ -82,7 +82,6 @@ then
# rescuing paths and is never meant to remove what
# is not in the named tree-ish.
git-ls-tree -r "$new" "$@" |
sed -ne 's/^\([0-7]*\) blob \(.*\)$/\1 \2/p' |
git-update-index --index-info || exit $?
fi
git-checkout-index -f -u -- "$@"

View File

@ -3,7 +3,7 @@
# Copyright (c) 2005 Junio C Hamano.
#
. git-sh-setup || die "Not a git archive."
. git-sh-setup
usage="usage: $0 "'[-v] <upstream> [<head>]

View File

@ -9,7 +9,7 @@
unset CDPATH
usage() {
echo >&2 "* git clone [-l [-s]] [-q] [-u <upload-pack>] [-n] <repo> <dir>"
echo >&2 "* git clone [-l [-s]] [-q] [-u <upload-pack>] [-n] <repo> [<dir>]"
exit 1
}
@ -23,7 +23,7 @@ fi
http_fetch () {
# $1 = Remote, $2 = Local
curl -nsf $curl_extra_args "$1" >"$2"
curl -nsfL $curl_extra_args "$1" >"$2"
}
clone_dumb_http () {
@ -96,7 +96,10 @@ if base=$(get_repo_base "$repo"); then
fi
dir="$2"
mkdir "$dir" &&
# Try using "humanish" part of source repo if user didn't specify one
[ -z "$dir" ] && dir=$(echo "$repo" | sed -e 's|/$||' -e 's|:*/*\.git$||' -e 's|.*/||g')
[ -e "$dir" ] && echo "$dir already exists." && usage
mkdir -p "$dir" &&
D=$(
(cd "$dir" && git-init-db && pwd)
) &&
@ -163,7 +166,7 @@ yes,yes)
rm -f "$D/.git/TMP_ALT"
if test -f "$D/.git/TMP_ALT"
then
( cd $D &&
( cd "$D" &&
. git-parse-remote &&
resolve_alternates "$repo" <"./.git/TMP_ALT" ) |
while read alt
@ -191,7 +194,7 @@ yes,yes)
;;
esac
cd $D || exit
cd "$D" || exit
if test -f ".git/HEAD"
then
@ -202,8 +205,16 @@ then
mkdir -p .git/remotes &&
echo >.git/remotes/origin \
"URL: $repo
Pull: $head_points_at:origin"
cp ".git/refs/heads/$head_points_at" .git/refs/heads/origin
Pull: $head_points_at:origin" &&
cp ".git/refs/heads/$head_points_at" .git/refs/heads/origin &&
find .git/refs/heads -type f -print |
while read ref
do
head=`expr "$ref" : '.git/refs/heads/\(.*\)'` &&
test "$head_points_at" = "$head" ||
test "origin" = "$head" ||
echo "Pull: ${head}:${head}"
done >>.git/remotes/origin
esac
case "$no_checkout" in

View File

@ -3,7 +3,7 @@
# Copyright (c) 2005 Linus Torvalds
#
. git-sh-setup || die "Not a git archive"
. git-sh-setup
usage () {
die 'git commit [-a] [-s] [-v | --no-verify] [-m <message> | -F <logfile> | (-C|-c) <commit>] [-e] [<path>...]'
@ -92,10 +92,13 @@ tt*)
esac
case "$all,$#" in
t,*)
t,0)
git-diff-files --name-only -z |
git-update-index --remove -z --stdin
;;
t,*)
die "Cannot use -a and explicit files at the same time."
;;
,0)
;;
*)
@ -184,7 +187,7 @@ then
}
'
set_author_env=`git-cat-file commit "$use_commit" |
sed -ne "$pick_author_script"`
LANG=C LC_ALL=C sed -ne "$pick_author_script"`
eval "$set_author_env"
export GIT_AUTHOR_NAME
export GIT_AUTHOR_EMAIL

View File

@ -1,83 +0,0 @@
# Pass --without docs to rpmbuild if you don't want the documetnation
Name: git-core
Version: @@VERSION@@
Release: 1%{?dist}
Summary: Git core and tools
License: GPL
Group: Development/Tools
URL: http://kernel.org/pub/software/scm/git/
Source: http://kernel.org/pub/software/scm/git/%{name}-%{version}.tar.gz
BuildRequires: zlib-devel, openssl-devel, curl-devel %{!?_without_docs:, xmlto, asciidoc > 6.0.3}
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
Requires: zlib >= 1.2, rsync, rcs, curl, less, openssh-clients, python >= 2.3, tk >= 8.4
%description
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.
%prep
%setup -q
%build
make %{_smp_mflags} CFLAGS="$RPM_OPT_FLAGS" WITH_OWN_SUBPROCESS_PY=YesPlease \
prefix=%{_prefix} all %{!?_without_docs: doc}
%install
rm -rf $RPM_BUILD_ROOT
make %{_smp_mflags} DESTDIR=$RPM_BUILD_ROOT WITH_OWN_SUBPROCESS_PY=YesPlease \
prefix=%{_prefix} mandir=%{_mandir} \
install %{!?_without_docs: install-doc}
%clean
rm -rf $RPM_BUILD_ROOT
%files
%defattr(-,root,root)
%{_bindir}/*
%{_datadir}/git-core/
%doc README COPYING Documentation/*.txt
%{!?_without_docs: %doc Documentation/*.html }
%{!?_without_docs: %{_mandir}/man1/*.1*}
%{!?_without_docs: %{_mandir}/man7/*.7*}
%changelog
* Tue Sep 27 2005 H. Peter Anvin <hpa@zytor.com>
- parallelize build
- COPTS -> CFLAGS
* Fri Sep 16 2005 Chris Wright <chrisw@osdl.org> 0.99.6-1
- update to 0.99.6
* Fri Sep 16 2005 Horst H. von Brand <vonbrand@inf.utfsm.cl>
- Linus noticed that less is required, added to the dependencies
* Sun Sep 11 2005 Horst H. von Brand <vonbrand@inf.utfsm.cl>
- Updated dependencies
- Don't assume manpages are gzipped
* Thu Aug 18 2005 Chris Wright <chrisw@osdl.org> 0.99.4-4
- drop sh_utils, sh-utils, diffutils, mktemp, and openssl Requires
- use RPM_OPT_FLAGS in spec file, drop patch0
* Wed Aug 17 2005 Tom "spot" Callaway <tcallawa@redhat.com> 0.99.4-3
- use dist tag to differentiate between branches
- use rpm optflags by default (patch0)
- own %{_datadir}/git-core/
* Mon Aug 15 2005 Chris Wright <chrisw@osdl.org>
- update spec file to fix Buildroot, Requires, and drop Vendor
* Sun Aug 07 2005 Horst H. von Brand <vonbrand@inf.utfsm.cl>
- Redid the description
- Cut overlong make line, loosened changelog a bit
- I think Junio (or perhaps OSDL?) should be vendor...
* Thu Jul 14 2005 Eric Biederman <ebiederm@xmission.com>
- Add the man pages, and the --without docs build option
* Wed Jul 7 2005 Chris Wright <chris@osdl.org>
- initial git spec file

View File

@ -1,7 +1,25 @@
#!/bin/sh
#
# Copyright (c) 2005 Junio C Hamano
#
. git-sh-setup
dc </dev/null 2>/dev/null || {
# This is not a real DC at all -- it just knows how
# this script feeds DC and does the computation itself.
dc () {
while read a b
do
case $a,$b in
0,) acc=0 ;;
*,+) acc=$(($acc + $a)) ;;
p,) echo "$acc" ;;
esac
done
}
}
echo $(find "$GIT_DIR/objects"/?? -type f -print 2>/dev/null | wc -l) objects, \
$({
echo 0

225
git-cvsexportcommit.perl Executable file
View File

@ -0,0 +1,225 @@
#!/usr/bin/perl -w
use strict;
use Getopt::Std;
use File::Temp qw(tempdir);
use Data::Dumper;
use File::Basename qw(basename);
unless ($ENV{GIT_DIR} && -r $ENV{GIT_DIR}){
die "GIT_DIR is not defined or is unreadable";
}
our ($opt_h, $opt_p, $opt_v, $opt_c );
getopts('hpvc');
$opt_h && usage();
die "Need at least one commit identifier!" unless @ARGV;
# setup a tempdir
our ($tmpdir, $tmpdirname) = tempdir('git-cvsapplycommit-XXXXXX',
TMPDIR => 1,
CLEANUP => 1);
print Dumper(@ARGV);
# resolve target commit
my $commit;
$commit = pop @ARGV;
$commit = `git-rev-parse --verify "$commit"^0`;
chomp $commit;
if ($?) {
die "The commit reference $commit did not resolve!";
}
# resolve what parent we want
my $parent;
if (@ARGV) {
$parent = pop @ARGV;
$parent = `git-rev-parse --verify "$parent"^0"`;
chomp $parent;
if ($?) {
die "The parent reference did not resolve!";
}
}
# find parents from the commit itself
my @commit = `git-cat-file commit $commit`;
my @parents;
foreach my $p (@commit) {
if ($p =~ m/^$/) { # end of commit headers, we're done
last;
}
if ($p =~ m/^parent (\w{40})$/) { # found a parent
push @parents, $1;
}
}
if ($parent) {
# double check that it's a valid parent
foreach my $p (@parents) {
my $found;
if ($p eq $parent) {
$found = 1;
last;
}; # found it
die "Did not find $parent in the parents for this commit!";
}
} else { # we don't have a parent from the cmdline...
if (@parents == 1) { # it's safe to get it from the commit
$parent = $parents[0];
} else { # or perhaps not!
die "This commit has more than one parent -- please name the parent you want to use explicitly";
}
}
$opt_v && print "Applying to CVS commit $commit from parent $parent\n";
# grab the commit message
`git-cat-file commit $commit | sed -e '1,/^\$/d' > .msg`;
$? && die "Error extracting the commit message";
my (@afiles, @dfiles, @mfiles);
my @files = `git-diff-tree -r $parent $commit`;
print @files;
$? && die "Error in git-diff-tree";
foreach my $f (@files) {
chomp $f;
my @fields = split(m/\s+/, $f);
if ($fields[4] eq 'A') {
push @afiles, $fields[5];
}
if ($fields[4] eq 'M') {
push @mfiles, $fields[5];
}
if ($fields[4] eq 'R') {
push @dfiles, $fields[5];
}
}
$opt_v && print "The commit affects:\n ";
$opt_v && print join ("\n ", @afiles,@mfiles,@dfiles) . "\n\n";
undef @files; # don't need it anymore
# check that the files are clean and up to date according to cvs
my $dirty;
foreach my $f (@afiles, @mfiles, @dfiles) {
# TODO:we need to handle removed in cvs and/or new (from git)
my $status = `cvs -q status "$f" | grep '^File: '`;
unless ($status =~ m/Status: Up-to-date$/) {
$dirty = 1;
warn "File $f not up to date in your CVS checkout!\n";
}
}
if ($dirty) {
die "Exiting: your CVS tree is not clean for this merge.";
}
###
### NOTE: if you are planning to die() past this point
### you MUST call cleanupcvs(@files) before die()
###
print "'Patching' binary files\n";
my @bfiles = `git-diff-tree -p $parent $commit | grep '^Binary'`;
@bfiles = map { chomp } @bfiles;
foreach my $f (@bfiles) {
# check that the file in cvs matches the "old" file
# extract the file to $tmpdir and comparre with cmp
my $tree = `git-rev-parse $parent^{tree} `;
chomp $tree;
my $blob = `git-ls-tree $tree "$f" | cut -f 1 | cut -d ' ' -f 3`;
chomp $blob;
`git-cat-file blob $blob > $tmpdir/blob`;
`cmp -q $f $tmpdir/blob`;
if ($?) {
warn "Binary file $f in CVS does not match parent.\n";
$dirty = 1;
next;
}
# replace with the new file
`git-cat-file blob $blob > $f`;
# TODO: something smart with file modes
}
if ($dirty) {
cleanupcvs(@files);
die "Exiting: Binary files in CVS do not match parent";
}
## apply non-binary changes
my $fuzz = $opt_p ? 0 : 2;
print "Patching non-binary files\n";
print `(git-diff-tree -p $parent -p $commit | patch -p1 -F $fuzz ) 2>&1`;
my $dirtypatch = 0;
if (($? >> 8) == 2) {
cleanupcvs(@files);
die "Exiting: Patch reported serious trouble -- you will have to apply this patch manually";
} elsif (($? >> 8) == 1) { # some hunks failed to apply
$dirtypatch = 1;
}
foreach my $f (@afiles) {
`cvs add $f`;
if ($?) {
$dirty = 1;
warn "Failed to cvs add $f -- you may need to do it manually";
}
}
foreach my $f (@dfiles) {
`cvs rm -f $f`;
if ($?) {
$dirty = 1;
warn "Failed to cvs rm -f $f -- you may need to do it manually";
}
}
print "Commit to CVS\n";
my $commitfiles = join(' ', @afiles, @mfiles, @dfiles);
my $cmd = "cvs commit -F .msg $commitfiles";
if ($dirtypatch) {
print "NOTE: One or more hunks failed to apply cleanly.\n";
print "Resolve the conflicts and then commit using:\n";
print "\n $cmd\n\n";
exit(1);
}
if ($opt_c) {
print "Autocommit\n $cmd\n";
print `cvs commit -F .msg $commitfiles 2>&1`;
if ($?) {
cleanupcvs(@files);
die "Exiting: The commit did not succeed";
}
print "Committed successfully to CVS\n";
} else {
print "Ready for you to commit, just run:\n\n $cmd\n";
}
sub usage {
print STDERR <<END;
Usage: GIT_DIR=/path/to/.git ${\basename $0} [-h] [-p] [-v] [-c] [ parent ] commit
END
exit(1);
}
# ensure cvs is clean before we die
sub cleanupcvs {
my @files = @_;
foreach my $f (@files) {
`cvs -q update -C "$f"`;
if ($?) {
warn "Warning! Failed to cleanup state of $f\n";
}
}
}

View File

@ -437,7 +437,11 @@ unless(-d $git_dir) {
"Either use the correct '-o branch' option,\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) {
warn "Cannot read the last branch name: $! -- assuming 'master'\n";
$last_branch = "master";
@ -498,7 +502,7 @@ unless($pid) {
if ($opt_P) {
exec("cat", $opt_P);
} else {
exec("cvsps",@opt,"-u","-A",'--root',$opt_d,$cvs_tree);
exec("cvsps","--norc",@opt,"-u","-A",'--root',$opt_d,$cvs_tree);
die "Could not start cvsps: $!\n";
}
}
@ -829,8 +833,7 @@ if($orig_branch) {
print "DONE; creating $orig_branch branch\n" if $opt_v;
system("cp","$git_dir/refs/heads/$opt_o","$git_dir/refs/heads/master")
unless -f "$git_dir/refs/heads/master";
unlink("$git_dir/HEAD");
symlink("refs/heads/$orig_branch","$git_dir/HEAD");
system('git-update-ref', 'HEAD', "$orig_branch");
unless ($opt_i) {
system('git checkout');
die "checkout failed: $?\n" if $?;

Some files were not shown because too many files have changed in this diff Show More