Merge with git://kernel.org/pub/scm/git/git.git

This commit is contained in:
Martin Langhoff 2006-05-08 10:03:37 +12:00
commit 50c08d4872
58 changed files with 2869 additions and 840 deletions

View File

@ -64,9 +64,11 @@ core.ignoreStat::
slow, such as Microsoft Windows. See gitlink:git-update-index[1].
False by default.
core.onlyUseSymrefs::
Always use the "symref" format instead of symbolic links for HEAD
and other symbolic reference files. True by default.
core.preferSymlinkRefs::
Instead of the default "symref" format for HEAD
and other symbolic reference files, use symbolic links.
This is sometimes needed to work with old scripts that
expect HEAD to be a symbolic link.
core.repositoryFormatVersion::
Internal variable identifying the repository format and layout

View File

@ -26,7 +26,7 @@ OPTIONS
-v::
Be verbose.
--::
\--::
This option can be used to separate command-line options from
the list of files, (useful when filenames might be mistaken
for command-line options).

View File

@ -63,7 +63,7 @@ OPTIONS
Only meaningful with `--stdin`; paths are separated with
NUL character instead of LF.
--::
\--::
Do not interpret any more arguments as options.
The order of the flags used to matter, but not anymore.

View File

@ -11,11 +11,20 @@ SYNOPSIS
DESCRIPTION
-----------
Each commit between the fork-point and <head> is examined, and compared against
the change each commit between the fork-point and <upstream> introduces.
Commits already included in upstream are prefixed with '-' (meaning "drop from
my local pull"), while commits missing from upstream are prefixed with '+'
(meaning "add to the updated upstream").
The changeset (or "diff") of each commit between the fork-point and <head>
is compared against each commit between the fork-point and <upstream>.
Every commit with a changeset that doesn't exist in the other branch
has its id (sha1) reported, prefixed by a symbol. Those existing only
in the <upstream> branch are prefixed with a minus (-) sign, and those
that only exist in the <head> branch are prefixed with a plus (+) symbol.
Because git-cherry compares the changeset rather than the commit id
(sha1), you can use git-cherry to find out if a commit you made locally
has been applied <upstream> under a different commit id. For example,
this will happen if you're feeding patches <upstream> via email rather
than pushing or pulling commits directly.
OPTIONS
-------

View File

@ -101,7 +101,7 @@ OPTIONS
is not allowed.
Examples
~~~~~~~~
--------
Clone from upstream::
+

View File

@ -106,7 +106,7 @@ but can be used to amend a merge commit.
index and the latest commit does not match on the
specified paths to avoid confusion.
--::
\--::
Do not interpret any more arguments as options.
<file>...::

View File

@ -7,13 +7,23 @@ git-count-objects - Reports on unpacked objects
SYNOPSIS
--------
'git-count-objects'
'git-count-objects' [-v]
DESCRIPTION
-----------
This counts the number of unpacked object files and disk space consumed by
them, to help you decide when it is a good time to repack.
OPTIONS
-------
-v::
In addition to the number of loose objects and disk
space consumed, it reports the number of in-pack
objects, and number of objects that can be removed by
running `git-prune-packed`.
Author
------
Written by Junio C Hamano <junkio@cox.net>

View File

@ -92,7 +92,7 @@ separated with a single space are given.
Furthermore, it lists only files which were modified
from all parents.
-cc::
--cc::
This flag changes the way a merge commit patch is displayed,
in a similar way to the '-c' option. It implies the '-c'
and '-p' options and further compresses the patch output

View File

@ -29,6 +29,7 @@ CONFIGURATION
git-imap-send requires the following values in the repository
configuration file (shown with examples):
..........................
[imap]
Folder = "INBOX.Drafts"
@ -38,8 +39,9 @@ configuration file (shown with examples):
[imap]
Host = imap.server.com
User = bob
Password = pwd
Pass = pwd
Port = 143
..........................
BUGS

View File

@ -51,7 +51,7 @@ git log v2.6.12.. include/scsi drivers/scsi::
Show all commits since version 'v2.6.12' that changed any file
in the include/scsi or drivers/scsi subdirectories
git log --since="2 weeks ago" -- gitk::
git log --since="2 weeks ago" \-- gitk::
Show the changes during the last two weeks to the file 'gitk'.
The "--" is necessary to avoid confusion with the *branch* named

View File

@ -106,7 +106,7 @@ OPTIONS
lines, show only handful hexdigits prefix.
Non default number of digits can be specified with --abbrev=<n>.
--::
\--::
Do not interpret any more arguments as options.
<file>::

View File

@ -8,7 +8,7 @@ git-merge-index - Runs a merge for files needing merging
SYNOPSIS
--------
'git-merge-index' [-o] [-q] <merge-program> (-a | -- | <file>\*)
'git-merge-index' [-o] [-q] <merge-program> (-a | \-- | <file>\*)
DESCRIPTION
-----------
@ -19,7 +19,7 @@ files are passed as arguments 5, 6 and 7.
OPTIONS
-------
--::
\--::
Do not interpret any more arguments as options.
-a::

View File

@ -41,6 +41,7 @@ Enter git-name-rev:
------------
% git name-rev 33db5f4d9027a10e477ccf054b2c1ab94f74c85a
33db5f4d9027a10e477ccf054b2c1ab94f74c85a tags/v0.99^0~940
------------
Now you are wiser, because you know that it happened 940 revisions before v0.99.

View File

@ -28,7 +28,7 @@ OPTIONS
Do not remove anything; just report what it would
remove.
--::
\--::
Do not interpret any more arguments as options.
<head>...::

View File

@ -38,6 +38,7 @@ OPTIONS
-d::
After packing, if the newly created packs make some
existing packs redundant, remove the redundant packs.
Also runs gitlink:git-prune-packed[1].
-l::
Pass the `--local` option to `git pack-objects`, see

View File

@ -34,10 +34,10 @@ convert the value to the canonical form (simple decimal number for int,
a "true" or "false" string for bool). If no type specifier is passed,
no checks or transformations are performed on the value.
This command will fail if
This command will fail if:
. .git/config is invalid,
. .git/config can not be written to,
. The .git/config file is invalid,
. Can not write to .git/config,
. no section was provided,
. the section or key is invalid,
. you try to unset an option which does not exist, or
@ -49,7 +49,7 @@ OPTIONS
--replace-all::
Default behaviour is to replace at most one line. This replaces
all lines matching the key (and optionally the value_regex)
all lines matching the key (and optionally the value_regex).
--get::
Get the value for a given key (optionally filtered by a regex
@ -59,6 +59,9 @@ OPTIONS
Like get, but does not fail if the number of values for the key
is not exactly one.
--get-regexp::
Like --get-all, but interprets the name as a regular expression.
--unset::
Remove the line matching the key from .git/config.

View File

@ -43,7 +43,7 @@ OPTIONS
Commit to make the current HEAD.
Examples
~~~~~~~~
--------
Undo a commit and redo::
+

View File

@ -32,7 +32,7 @@ OPTIONS
-v::
Be verbose.
--::
\--::
This option can be used to separate command-line options from
the list of files, (useful when filenames might be mistaken
for command-line options).

View File

@ -13,9 +13,16 @@ SYNOPSIS
DESCRIPTION
-----------
Reads a packed archive (.pack) from the standard input, and
expands the objects contained in the pack into "one-file
one-object" format in $GIT_OBJECT_DIRECTORY.
Read a packed archive (.pack) from the standard input, expanding
the objects contained within and writing them into the repository in
"loose" (one object per file) format.
Objects that already exist in the repository will *not* be unpacked
from the pack-file. Therefore, nothing will be unpacked if you use
this command on a pack-file that exists within the target repository.
Please see the `git-repack` documentation for options to generate
new packs and replace existing ones.
OPTIONS
-------

View File

@ -10,12 +10,12 @@ SYNOPSIS
--------
[verse]
'git-update-index'
[--add] [--remove | --force-remove] [--replace]
[--refresh [-q] [--unmerged] [--ignore-missing]]
[--add] [--remove | --force-remove] [--replace]
[--refresh] [-q] [--unmerged] [--ignore-missing]
[--cacheinfo <mode> <object> <file>]\*
[--chmod=(+|-)x]
[--assume-unchanged | --no-assume-unchanged]
[--really-refresh]
[--really-refresh] [--unresolve]
[--info-only] [--index-info]
[-z] [--stdin]
[--verbose]
@ -80,6 +80,10 @@ OPTIONS
filesystem that has very slow lstat(2) system call
(e.g. cifs).
--unresolve::
Restores the 'unmerged' or 'needs updating' state of a
file during a merge if it was cleared by accident.
--info-only::
Do not create objects in the object database for all
<file> arguments that follow this flag; just insert
@ -109,7 +113,7 @@ OPTIONS
Only meaningful with `--stdin`; paths are separated with
NUL character instead of LF.
--::
\--::
Do not interpret any more arguments as options.
<file>::

View File

@ -25,7 +25,7 @@ OPTIONS
-v::
After verifying the pack, show list of objects contained
in the pack.
--::
\--::
Do not interpret any more arguments as options.
OUTPUT FORMAT

View File

@ -58,7 +58,7 @@ git-whatchanged -p v2.6.12.. include/scsi drivers/scsi::
Show as patches the commits since version 'v2.6.12' that changed
any file in the include/scsi or drivers/scsi subdirectories
git-whatchanged --since="2 weeks ago" -- gitk::
git-whatchanged --since="2 weeks ago" \-- gitk::
Show the changes during the last two weeks to the file 'gitk'.
The "--" is necessary to avoid confusion with the *branch* named

View File

@ -31,7 +31,7 @@ gitk v2.6.12.. include/scsi drivers/scsi::
Show as the changes since version 'v2.6.12' that changed any
file in the include/scsi or drivers/scsi subdirectories
gitk --since="2 weeks ago" -- gitk::
gitk --since="2 weeks ago" \-- gitk::
Show the changes during the last two weeks to the file 'gitk'.
The "--" is necessary to avoid confusion with the *branch* named

View File

@ -1,39 +1,71 @@
object::
The unit of storage in git. It is uniquely identified by
the SHA1 of its contents. Consequently, an object can not
be changed.
alternate object database::
Via the alternates mechanism, a repository can inherit part of its
object database from another object database, which is called
"alternate".
object name::
The unique identifier of an object. The hash of the object's contents
using the Secure Hash Algorithm 1 and usually represented by the 40
character hexadecimal encoding of the hash of the object (possibly
followed by a white space).
SHA1::
Synonym for object name.
object identifier::
Synonym for object name.
hash::
In git's context, synonym to object name.
object database::
Stores a set of "objects", and an individual object is identified
by its object name. The objects usually live in `$GIT_DIR/objects/`.
bare repository::
A bare repository is normally an appropriately named
directory with a `.git` suffix that does not have a
locally checked-out copy of any of the files under revision
control. That is, all of the `git` administrative and
control files that would normally be present in the
hidden `.git` sub-directory are directly present in
the `repository.git` directory instead, and no other files
are present and checked out. Usually publishers of public
repositories make bare repositories available.
blob object::
Untyped object, e.g. the contents of a file.
tree object::
An object containing a list of file names and modes along with refs
to the associated blob and/or tree objects. A tree is equivalent
to a directory.
branch::
A non-cyclical graph of revisions, i.e. the complete history of
a particular revision, which is called the branch head. The
branch heads are stored in `$GIT_DIR/refs/heads/`.
tree::
Either a working tree, or a tree object together with the
dependent blob and tree objects (i.e. a stored representation
of a working tree).
cache::
Obsolete for: index.
chain::
A list of objects, where each object in the list contains a
reference to its successor (for example, the successor of a commit
could be one of its parents).
changeset::
BitKeeper/cvsps speak for "commit". Since git does not store
changes, but states, it really does not make sense to use
the term "changesets" with git.
checkout::
The action of updating the working tree to a revision which was
stored in the object database.
cherry-picking::
In SCM jargon, "cherry pick" means to choose a subset of
changes out of a series of changes (typically commits)
and record them as a new series of changes on top of
different codebase. In GIT, this is performed by
"git cherry-pick" command to extract the change
introduced by an existing commit and to record it based
on the tip of the current branch as a new commit.
clean::
A working tree is clean, if it corresponds to the revision
referenced by the current head. Also see "dirty".
commit::
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.
commit object::
An object which contains the information about a particular
revision, such as parents, committer, author, date and the
tree object which corresponds to the top directory of the
stored revision.
core git::
Fundamental data structures and utilities of git. Exposes only
limited source code management tools.
DAG::
Directed acyclic graph. The commit objects form a directed acyclic
@ -41,6 +73,63 @@ DAG::
objects is acyclic (there is no chain which begins and ends with the
same object).
dircache::
You are *waaaaay* behind.
dirty::
A working tree is said to be dirty if it contains modifications
which have not been committed to the current branch.
directory::
The list you get with "ls" :-)
ent::
Favorite synonym to "tree-ish" by some total geeks. See
`http://en.wikipedia.org/wiki/Ent_(Middle-earth)` for an in-depth
explanation.
fast forward::
A fast-forward is a special type of merge where you have
a revision and you are "merging" another branch's changes
that happen to be a descendant of what you have.
In such these cases, you do not make a new merge commit but
instead just update to his revision. This will happen
frequently on a tracking branch of a remote repository.
fetch::
Fetching a branch means to get the branch's head ref from a
remote repository, to find out which objects are missing from
the local object database, and to get them, too.
file system::
Linus Torvalds originally designed git to be a user space file
system, i.e. the infrastructure to hold files and directories.
That ensured the efficiency and speed of git.
git archive::
Synonym for repository (for arch people).
hash::
In git's context, synonym to object name.
head::
The top of a branch. It contains a ref to the corresponding
commit object.
head ref::
A ref pointing to a head. Often, this is abbreviated to "head".
Head refs are stored in `$GIT_DIR/refs/heads/`.
hook::
During the normal execution of several git commands,
call-outs are made to optional scripts that allow
a developer to add functionality or checking.
Typically, the hooks allow for a command to be pre-verified
and potentially aborted, and allow for a post-notification
after the operation is done.
The hook scripts are found in the `$GIT_DIR/hooks/` directory,
and are enabled by simply making them executable.
index::
A collection of files with stat information, whose contents are
stored as objects. The index is a stored version of your working
@ -53,92 +142,167 @@ index entry::
yet finished (i.e. if the index contains multiple versions of
that file).
unmerged index:
An index which contains unmerged index entries.
master::
The default development branch. Whenever you create a git
repository, a branch named "master" is created, and becomes
the active branch. In most cases, this contains the local
development, though that is purely conventional and not required.
cache::
Obsolete for: index.
merge::
To merge branches means to try to accumulate the changes since a
common ancestor and apply them to the first branch. An automatic
merge uses heuristics to accomplish that. Evidently, an automatic
merge can fail.
working tree::
The set of files and directories currently being worked on,
i.e. you can work in your working tree without using git at all.
object::
The unit of storage in git. It is uniquely identified by
the SHA1 of its contents. Consequently, an object can not
be changed.
directory::
The list you get with "ls" :-)
object database::
Stores a set of "objects", and an individual object is identified
by its object name. The objects usually live in `$GIT_DIR/objects/`.
revision::
A particular state of files and directories which was stored in
the object database. It is referenced by a commit object.
object identifier::
Synonym for object name.
checkout::
The action of updating the working tree to a revision which was
stored in the object database.
object name::
The unique identifier of an object. The hash of the object's contents
using the Secure Hash Algorithm 1 and usually represented by the 40
character hexadecimal encoding of the hash of the object (possibly
followed by a white space).
commit::
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.
object type:
One of the identifiers "commit","tree","tag" and "blob" describing
the type of an object.
commit object::
An object which contains the information about a particular
revision, such as parents, committer, author, date and the
tree object which corresponds to the top directory of the
stored revision.
octopus::
To merge more than two branches. Also denotes an intelligent
predator.
origin::
The default upstream tracking branch. Most projects have at
least one upstream project which they track. By default
'origin' is used for that purpose. New upstream updates
will be fetched into this branch; you should never commit
to it yourself.
pack::
A set of objects which have been compressed into one file (to save
space or to transmit them efficiently).
pack index::
The list of identifiers, and other information, of the objects in a
pack, to assist in efficiently accessing the contents of a pack.
parent::
A commit object contains a (possibly empty) list of the logical
predecessor(s) in the line of development, i.e. its parents.
changeset::
BitKeeper/cvsps speak for "commit". Since git does not store
changes, but states, it really does not make sense to use
the term "changesets" with git.
pickaxe::
The term pickaxe refers to an option to the diffcore routines
that help select changes that add or delete a given text string.
With the --pickaxe-all option, it can be used to view the
full changeset that introduced or removed, say, a particular
line of text. See gitlink:git-diff[1].
clean::
A working tree is clean, if it corresponds to the revision
referenced by the current head.
plumbing::
Cute name for core git.
dirty::
A working tree is said to be dirty if it contains modifications
which have not been committed to the current branch.
porcelain::
Cute name for programs and program suites depending on core git,
presenting a high level access to core git. Porcelains expose
more of a SCM interface than the plumbing.
head::
The top of a branch. It contains a ref to the corresponding
commit object.
pull::
Pulling a branch means to fetch it and merge it.
branch::
A non-cyclical graph of revisions, i.e. the complete history of
a particular revision, which is called the branch head. The
branch heads are stored in `$GIT_DIR/refs/heads/`.
push::
Pushing a branch means to get the branch's head ref from a remote
repository, find out if it is an ancestor to the branch's local
head ref is a direct, and in that case, putting all objects, which
are reachable from the local head ref, and which are missing from
the remote repository, into the remote object database, and updating
the remote head ref. If the remote head is not an ancestor to the
local head, the push fails.
master::
The default branch. Whenever you create a git repository, a branch
named "master" is created, and becomes the active branch. In most
cases, this contains the local development.
reachable::
An object is reachable from a ref/commit/tree/tag, if there is a
chain leading from the latter to the former.
origin::
The default upstream branch. Most projects have one upstream
project which they track, and by default 'origin' is used for
that purpose. New updates from upstream will be fetched into
this branch; you should never commit to it yourself.
rebase::
To clean a branch by starting from the head of the main line of
development ("master"), and reapply the (possibly cherry-picked)
changes from that branch.
ref::
A 40-byte hex representation of a SHA1 pointing to a particular
object. These may be stored in `$GIT_DIR/refs/`.
A 40-byte hex representation of a SHA1 or a name that denotes
a particular object. These may be stored in `$GIT_DIR/refs/`.
head ref::
A ref pointing to a head. Often, this is abbreviated to "head".
Head refs are stored in `$GIT_DIR/refs/heads/`.
refspec::
A refspec is used by fetch and push to describe the mapping
between remote ref and local ref. They are combined with
a colon in the format <src>:<dst>, preceded by an optional
plus sign, +. For example:
`git fetch $URL refs/heads/master:refs/heads/origin`
means "grab the master branch head from the $URL and store
it as my origin branch head".
And `git push $URL refs/heads/master:refs/heads/to-upstream`
means "publish my master branch head as to-upstream master head
at $URL". See also gitlink:git-push[1]
repository::
A collection of refs together with an object database containing
all objects, which are reachable from the refs, possibly accompanied
by meta data from one or more porcelains. A repository can
share an object database with other repositories.
resolve::
The action of fixing up manually what a failed automatic merge
left behind.
revision::
A particular state of files and directories which was stored in
the object database. It is referenced by a commit object.
rewind::
To throw away part of the development, i.e. to assign the head to
an earlier revision.
SCM::
Source code management (tool).
SHA1::
Synonym for object name.
topic branch::
A regular git branch that is used by a developer to
identify a conceptual line of development. Since branches
are very easy and inexpensive, it is often desirable to
have several small branches that each contain very well
defined concepts or small incremental yet related changes.
tracking branch::
A regular git branch that is used to follow changes from
another repository. A tracking branch should not contain
direct modifications or have local commits made to it.
A tracking branch can usually be identified as the
right-hand-side ref in a Pull: refspec.
tree object::
An object containing a list of file names and modes along with refs
to the associated blob and/or tree objects. A tree is equivalent
to a directory.
tree::
Either a working tree, or a tree object together with the
dependent blob and tree objects (i.e. a stored representation
of a working tree).
tree-ish::
A ref pointing to either a commit object, a tree object, or a
tag object pointing to a tag or commit or tree object.
ent::
Favorite synonym to "tree-ish" by some total geeks. See
`http://en.wikipedia.org/wiki/Ent_(Middle-earth)` for an in-depth
explanation.
tag object::
An object containing a ref pointing to another object, which can
contain a message just like a commit object. It can also
@ -153,101 +317,10 @@ tag::
A tag is most typically used to mark a particular point in the
commit ancestry chain.
merge::
To merge branches means to try to accumulate the changes since a
common ancestor and apply them to the first branch. An automatic
merge uses heuristics to accomplish that. Evidently, an automatic
merge can fail.
unmerged index:
An index which contains unmerged index entries.
octopus::
To merge more than two branches. Also denotes an intelligent
predator.
resolve::
The action of fixing up manually what a failed automatic merge
left behind.
rewind::
To throw away part of the development, i.e. to assign the head to
an earlier revision.
rebase::
To clean a branch by starting from the head of the main line of
development ("master"), and reapply the (possibly cherry-picked)
changes from that branch.
repository::
A collection of refs together with an object database containing
all objects, which are reachable from the refs, possibly accompanied
by meta data from one or more porcelains. A repository can
share an object database with other repositories.
git archive::
Synonym for repository (for arch people).
file system::
Linus Torvalds originally designed git to be a user space file
system, i.e. the infrastructure to hold files and directories.
That ensured the efficiency and speed of git.
alternate object database::
Via the alternates mechanism, a repository can inherit part of its
object database from another object database, which is called
"alternate".
reachable::
An object is reachable from a ref/commit/tree/tag, if there is a
chain leading from the latter to the former.
chain::
A list of objects, where each object in the list contains a
reference to its successor (for example, the successor of a commit
could be one of its parents).
fetch::
Fetching a branch means to get the branch's head ref from a
remote repository, to find out which objects are missing from
the local object database, and to get them, too.
pull::
Pulling a branch means to fetch it and merge it.
push::
Pushing a branch means to get the branch's head ref from a remote
repository, find out if it is an ancestor to the branch's local
head ref is a direct, and in that case, putting all objects, which
are reachable from the local head ref, and which are missing from
the remote repository, into the remote object database, and updating
the remote head ref. If the remote head is not an ancestor to the
local head, the push fails.
pack::
A set of objects which have been compressed into one file (to save
space or to transmit them efficiently).
pack index::
The list of identifiers, and other information, of the objects in a
pack, to assist in efficiently accessing the contents of a pack.
core git::
Fundamental data structures and utilities of git. Exposes only
limited source code management tools.
plumbing::
Cute name for core git.
porcelain::
Cute name for programs and program suites depending on core git,
presenting a high level access to core git. Porcelains expose
more of a SCM interface than the plumbing.
object type:
One of the identifiers "commit","tree","tag" and "blob" describing
the type of an object.
SCM::
Source code management (tool).
dircache::
You are *waaaaay* behind.
working tree::
The set of files and directories currently being worked on,
i.e. you can work in your working tree without using git at all.

View File

@ -48,7 +48,7 @@ This list is sorted alphabetically:
';
@keys=sort {uc($a) cmp uc($b)} keys %terms;
$pattern='(\b'.join('\b|\b',reverse @keys).'\b)';
$pattern='(\b(?<!link:git-)'.join('\b|\b(?<!link:git-)',reverse @keys).'\b)';
foreach $key (@keys) {
$terms{$key}=~s/$pattern/sprintf "<<ref_".no_spaces($1).",$1>>";/eg;
print '[[ref_'.no_spaces($key).']]'.$key."::\n"

View File

@ -28,8 +28,8 @@ all:
#
# Define NO_SETENV if you don't have setenv in the C library.
#
# Define USE_SYMLINK_HEAD if you want .git/HEAD to be a symbolic link.
# Don't enable it on Windows.
# Define NO_SYMLINK_HEAD if you never want .git/HEAD to be a symbolic link.
# Enable it on Windows. By default, symrefs are still used.
#
# Define PPC_SHA1 environment variable when running make to make use of
# a bundled SHA1 routine optimized for PowerPC.
@ -115,13 +115,13 @@ SPARSE_FLAGS = -D__BIG_ENDIAN__ -D__powerpc__
SCRIPT_SH = \
git-add.sh git-bisect.sh git-branch.sh git-checkout.sh \
git-cherry.sh git-clean.sh git-clone.sh git-commit.sh \
git-count-objects.sh git-diff.sh git-fetch.sh \
git-fetch.sh \
git-format-patch.sh git-ls-remote.sh \
git-merge-one-file.sh git-parse-remote.sh \
git-prune.sh git-pull.sh git-push.sh git-rebase.sh \
git-prune.sh git-pull.sh git-rebase.sh \
git-repack.sh git-request-pull.sh git-reset.sh \
git-resolve.sh git-revert.sh git-rm.sh git-sh-setup.sh \
git-tag.sh git-verify-tag.sh git-whatchanged.sh \
git-tag.sh git-verify-tag.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 \
@ -139,7 +139,7 @@ SCRIPT_PYTHON = \
SCRIPTS = $(patsubst %.sh,%,$(SCRIPT_SH)) \
$(patsubst %.perl,%,$(SCRIPT_PERL)) \
$(patsubst %.py,%,$(SCRIPT_PYTHON)) \
git-cherry-pick git-show git-status
git-cherry-pick git-status
# The ones that do not have to link with lcrypto, lz nor xdiff.
SIMPLE_PROGRAMS = \
@ -167,7 +167,8 @@ PROGRAMS = \
git-name-rev$X git-pack-redundant$X git-repo-config$X git-var$X \
git-describe$X git-merge-tree$X git-blame$X git-imap-send$X
BUILT_INS = git-log$X
BUILT_INS = git-log$X git-whatchanged$X git-show$X \
git-count-objects$X git-diff$X git-push$X
# what 'all' will build and 'install' will install, in gitexecdir
ALL_PROGRAMS = $(PROGRAMS) $(SIMPLE_PROGRAMS) $(SCRIPTS)
@ -214,7 +215,7 @@ LIB_OBJS = \
$(DIFF_OBJS)
BUILTIN_OBJS = \
builtin-log.o builtin-help.o
builtin-log.o builtin-help.o builtin-count.o builtin-diff.o builtin-push.o
GITLIBS = $(LIB_FILE) $(XDIFF_LIB)
LIBS = $(GITLIBS) -lz
@ -263,6 +264,7 @@ ifeq ($(uname_O),Cygwin)
NO_D_TYPE_IN_DIRENT = YesPlease
NO_D_INO_IN_DIRENT = YesPlease
NO_STRCASESTR = YesPlease
NO_SYMLINK_HEAD = YesPlease
NEEDS_LIBICONV = YesPlease
# There are conflicting reports about this.
# On some boxes NO_MMAP is needed, and not so elsewhere.
@ -386,6 +388,9 @@ endif
ifdef NO_D_INO_IN_DIRENT
ALL_CFLAGS += -DNO_D_INO_IN_DIRENT
endif
ifdef NO_SYMLINK_HEAD
ALL_CFLAGS += -DNO_SYMLINK_HEAD
endif
ifdef NO_STRCASESTR
COMPAT_CFLAGS += -DNO_STRCASESTR
COMPAT_OBJS += compat/strcasestr.o
@ -505,9 +510,6 @@ $(patsubst %.py,%,$(SCRIPT_PYTHON)) : % : %.py
git-cherry-pick: git-revert
cp $< $@
git-show: git-whatchanged
cp $< $@
git-status: git-commit
cp $< $@
@ -562,10 +564,6 @@ git-http-push$X: revision.o http.o http-push.o $(LIB_FILE)
$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \
$(LIBS) $(CURL_LIBCURL) $(EXPAT_LIBEXPAT)
git-rev-list$X: rev-list.o $(LIB_FILE)
$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \
$(LIBS) $(OPENSSL_LIBSSL)
init-db.o: init-db.c
$(CC) -c $(ALL_CFLAGS) \
-DDEFAULT_GIT_TEMPLATE_DIR='"$(template_dir_SQ)"' $*.c

10
blame.c
View File

@ -515,9 +515,9 @@ static int compare_tree_path(struct rev_info* revs,
paths[1] = NULL;
diff_tree_setup_paths(get_pathspec(revs->prefix, paths),
&revs->diffopt);
&revs->pruning);
ret = rev_compare_tree(revs, c1->tree, c2->tree);
diff_tree_release_paths(&revs->diffopt);
diff_tree_release_paths(&revs->pruning);
return ret;
}
@ -531,9 +531,9 @@ static int same_tree_as_empty_path(struct rev_info *revs, struct tree* t1,
paths[1] = NULL;
diff_tree_setup_paths(get_pathspec(revs->prefix, paths),
&revs->diffopt);
&revs->pruning);
ret = rev_same_tree_as_empty(revs, t1);
diff_tree_release_paths(&revs->diffopt);
diff_tree_release_paths(&revs->pruning);
return ret;
}
@ -834,7 +834,7 @@ int main(int argc, const char **argv)
args[0] = filename;
args[1] = NULL;
diff_tree_setup_paths(args, &rev.diffopt);
diff_tree_setup_paths(args, &rev.pruning);
prepare_revision_walk(&rev);
process_commits(&rev, filename, &initial);

125
builtin-count.c Normal file
View File

@ -0,0 +1,125 @@
/*
* Builtin "git count-objects".
*
* Copyright (c) 2006 Junio C Hamano
*/
#include "cache.h"
#include "builtin.h"
static const char count_objects_usage[] = "git-count-objects [-v]";
static void count_objects(DIR *d, char *path, int len, int verbose,
unsigned long *loose,
unsigned long *loose_size,
unsigned long *packed_loose,
unsigned long *garbage)
{
struct dirent *ent;
while ((ent = readdir(d)) != NULL) {
char hex[41];
unsigned char sha1[20];
const char *cp;
int bad = 0;
if ((ent->d_name[0] == '.') &&
(ent->d_name[1] == 0 ||
((ent->d_name[1] == '.') && (ent->d_name[2] == 0))))
continue;
for (cp = ent->d_name; *cp; cp++) {
int ch = *cp;
if (('0' <= ch && ch <= '9') ||
('a' <= ch && ch <= 'f'))
continue;
bad = 1;
break;
}
if (cp - ent->d_name != 38)
bad = 1;
else {
struct stat st;
memcpy(path + len + 3, ent->d_name, 38);
path[len + 2] = '/';
path[len + 41] = 0;
if (lstat(path, &st) || !S_ISREG(st.st_mode))
bad = 1;
else
(*loose_size) += st.st_blocks;
}
if (bad) {
if (verbose) {
error("garbage found: %.*s/%s",
len + 2, path, ent->d_name);
(*garbage)++;
}
continue;
}
(*loose)++;
if (!verbose)
continue;
memcpy(hex, path+len, 2);
memcpy(hex+2, ent->d_name, 38);
hex[40] = 0;
if (get_sha1_hex(hex, sha1))
die("internal error");
if (has_sha1_pack(sha1))
(*packed_loose)++;
}
}
int cmd_count_objects(int ac, const char **av, char **ep)
{
int i;
int verbose = 0;
const char *objdir = get_object_directory();
int len = strlen(objdir);
char *path = xmalloc(len + 50);
unsigned long loose = 0, packed = 0, packed_loose = 0, garbage = 0;
unsigned long loose_size = 0;
for (i = 1; i < ac; i++) {
const char *arg = av[i];
if (*arg != '-')
break;
else if (!strcmp(arg, "-v"))
verbose = 1;
else
usage(count_objects_usage);
}
/* we do not take arguments other than flags for now */
if (i < ac)
usage(count_objects_usage);
memcpy(path, objdir, len);
if (len && objdir[len-1] != '/')
path[len++] = '/';
for (i = 0; i < 256; i++) {
DIR *d;
sprintf(path + len, "%02x", i);
d = opendir(path);
if (!d)
continue;
count_objects(d, path, len, verbose,
&loose, &loose_size, &packed_loose, &garbage);
closedir(d);
}
if (verbose) {
struct packed_git *p;
if (!packed_git)
prepare_packed_git();
for (p = packed_git; p; p = p->next) {
if (!p->pack_local)
continue;
packed += num_packed_objects(p);
}
printf("count: %lu\n", loose);
printf("size: %lu\n", loose_size / 2);
printf("in-pack: %lu\n", packed);
printf("prune-packable: %lu\n", packed_loose);
printf("garbage: %lu\n", garbage);
}
else
printf("%lu objects, %lu kilobytes\n",
loose, loose_size / 2);
return 0;
}

369
builtin-diff.c Normal file
View File

@ -0,0 +1,369 @@
/*
* Builtin "git diff"
*
* Copyright (c) 2006 Junio C Hamano
*/
#include "cache.h"
#include "commit.h"
#include "blob.h"
#include "tag.h"
#include "diff.h"
#include "diffcore.h"
#include "revision.h"
#include "log-tree.h"
#include "builtin.h"
/* NEEDSWORK: struct object has place for name but we _do_
* know mode when we extracted the blob out of a tree, which
* we currently lose.
*/
struct blobinfo {
unsigned char sha1[20];
const char *name;
};
static const char builtin_diff_usage[] =
"diff <options> <rev>{0,2} -- <path>*";
static int builtin_diff_files(struct rev_info *revs,
int argc, const char **argv)
{
int silent = 0;
while (1 < argc) {
const char *arg = argv[1];
if (!strcmp(arg, "--base"))
revs->max_count = 1;
else if (!strcmp(arg, "--ours"))
revs->max_count = 2;
else if (!strcmp(arg, "--theirs"))
revs->max_count = 3;
else if (!strcmp(arg, "-q"))
silent = 1;
else if (!strcmp(arg, "--raw"))
revs->diffopt.output_format = DIFF_FORMAT_RAW;
else
usage(builtin_diff_usage);
argv++; argc--;
}
/*
* Make sure there are NO revision (i.e. pending object) parameter,
* specified rev.max_count is reasonable (0 <= n <= 3), and
* there is no other revision filtering parameter.
*/
if (revs->pending_objects ||
revs->min_age != -1 ||
revs->max_age != -1 ||
3 < revs->max_count)
usage(builtin_diff_usage);
if (revs->max_count < 0 &&
(revs->diffopt.output_format == DIFF_FORMAT_PATCH))
revs->combine_merges = revs->dense_combined_merges = 1;
/*
* Backward compatibility wart - "diff-files -s" used to
* defeat the common diff option "-s" which asked for
* DIFF_FORMAT_NO_OUTPUT.
*/
if (revs->diffopt.output_format == DIFF_FORMAT_NO_OUTPUT)
revs->diffopt.output_format = DIFF_FORMAT_RAW;
return run_diff_files(revs, silent);
}
static void stuff_change(struct diff_options *opt,
unsigned old_mode, unsigned new_mode,
const unsigned char *old_sha1,
const unsigned char *new_sha1,
const char *old_name,
const char *new_name)
{
struct diff_filespec *one, *two;
if (memcmp(null_sha1, old_sha1, 20) &&
memcmp(null_sha1, new_sha1, 20) &&
!memcmp(old_sha1, new_sha1, 20))
return;
if (opt->reverse_diff) {
unsigned tmp;
const
const unsigned char *tmp_u;
const char *tmp_c;
tmp = old_mode; old_mode = new_mode; new_mode = tmp;
tmp_u = old_sha1; old_sha1 = new_sha1; new_sha1 = tmp_u;
tmp_c = old_name; old_name = new_name; new_name = tmp_c;
}
one = alloc_filespec(old_name);
two = alloc_filespec(new_name);
fill_filespec(one, old_sha1, old_mode);
fill_filespec(two, new_sha1, new_mode);
/* NEEDSWORK: shouldn't this part of diffopt??? */
diff_queue(&diff_queued_diff, one, two);
}
static int builtin_diff_b_f(struct rev_info *revs,
int argc, const char **argv,
struct blobinfo *blob,
const char *path)
{
/* Blob vs file in the working tree*/
struct stat st;
while (1 < argc) {
const char *arg = argv[1];
if (!strcmp(arg, "--raw"))
revs->diffopt.output_format = DIFF_FORMAT_RAW;
else
usage(builtin_diff_usage);
argv++; argc--;
}
if (lstat(path, &st))
die("'%s': %s", path, strerror(errno));
if (!(S_ISREG(st.st_mode) || S_ISLNK(st.st_mode)))
die("'%s': not a regular file or symlink", path);
stuff_change(&revs->diffopt,
canon_mode(st.st_mode), canon_mode(st.st_mode),
blob[0].sha1, null_sha1,
blob[0].name, path);
diffcore_std(&revs->diffopt);
diff_flush(&revs->diffopt);
return 0;
}
static int builtin_diff_blobs(struct rev_info *revs,
int argc, const char **argv,
struct blobinfo *blob)
{
/* Blobs */
unsigned mode = canon_mode(S_IFREG | 0644);
while (1 < argc) {
const char *arg = argv[1];
if (!strcmp(arg, "--raw"))
revs->diffopt.output_format = DIFF_FORMAT_RAW;
else
usage(builtin_diff_usage);
argv++; argc--;
}
stuff_change(&revs->diffopt,
mode, mode,
blob[0].sha1, blob[1].sha1,
blob[1].name, blob[1].name);
diffcore_std(&revs->diffopt);
diff_flush(&revs->diffopt);
return 0;
}
static int builtin_diff_index(struct rev_info *revs,
int argc, const char **argv)
{
int cached = 0;
while (1 < argc) {
const char *arg = argv[1];
if (!strcmp(arg, "--cached"))
cached = 1;
else if (!strcmp(arg, "--raw"))
revs->diffopt.output_format = DIFF_FORMAT_RAW;
else
usage(builtin_diff_usage);
argv++; argc--;
}
/*
* Make sure there is one revision (i.e. pending object),
* and there is no revision filtering parameters.
*/
if (!revs->pending_objects || revs->pending_objects->next ||
revs->max_count != -1 || revs->min_age != -1 ||
revs->max_age != -1)
usage(builtin_diff_usage);
return run_diff_index(revs, cached);
}
static int builtin_diff_tree(struct rev_info *revs,
int argc, const char **argv,
struct object_list *ent)
{
const unsigned char *(sha1[2]);
int swap = 1;
while (1 < argc) {
const char *arg = argv[1];
if (!strcmp(arg, "--raw"))
revs->diffopt.output_format = DIFF_FORMAT_RAW;
else
usage(builtin_diff_usage);
argv++; argc--;
}
/* We saw two trees, ent[0] and ent[1].
* unless ent[0] is unintesting, they are swapped
*/
if (ent[0].item->flags & UNINTERESTING)
swap = 0;
sha1[swap] = ent[0].item->sha1;
sha1[1-swap] = ent[1].item->sha1;
diff_tree_sha1(sha1[0], sha1[1], "", &revs->diffopt);
log_tree_diff_flush(revs);
return 0;
}
static int builtin_diff_combined(struct rev_info *revs,
int argc, const char **argv,
struct object_list *ent,
int ents)
{
const unsigned char (*parent)[20];
int i;
while (1 < argc) {
const char *arg = argv[1];
if (!strcmp(arg, "--raw"))
revs->diffopt.output_format = DIFF_FORMAT_RAW;
else
usage(builtin_diff_usage);
argv++; argc--;
}
if (!revs->dense_combined_merges && !revs->combine_merges)
revs->dense_combined_merges = revs->combine_merges = 1;
parent = xmalloc(ents * sizeof(*parent));
/* Again, the revs are all reverse */
for (i = 0; i < ents; i++)
memcpy(parent + i, ent[ents - 1 - i].item->sha1, 20);
diff_tree_combined(parent[0], parent + 1, ents - 1,
revs->dense_combined_merges, revs);
return 0;
}
static void add_head(struct rev_info *revs)
{
unsigned char sha1[20];
struct object *obj;
if (get_sha1("HEAD", sha1))
return;
obj = parse_object(sha1);
if (!obj)
return;
add_object(obj, &revs->pending_objects, NULL, "HEAD");
}
int cmd_diff(int argc, const char **argv, char **envp)
{
struct rev_info rev;
struct object_list *list, ent[100];
int ents = 0, blobs = 0, paths = 0;
const char *path = NULL;
struct blobinfo blob[2];
/*
* We could get N tree-ish in the rev.pending_objects list.
* Also there could be M blobs there, and P pathspecs.
*
* N=0, M=0:
* cache vs files (diff-files)
* N=0, M=2:
* compare two random blobs. P must be zero.
* N=0, M=1, P=1:
* compare a blob with a working tree file.
*
* N=1, M=0:
* tree vs cache (diff-index --cached)
*
* N=2, M=0:
* tree vs tree (diff-tree)
*
* Other cases are errors.
*/
git_config(git_diff_config);
init_revisions(&rev);
rev.diffopt.output_format = DIFF_FORMAT_PATCH;
argc = setup_revisions(argc, argv, &rev, NULL);
/* Do we have --cached and not have a pending object, then
* default to HEAD by hand. Eek.
*/
if (!rev.pending_objects) {
int i;
for (i = 1; i < argc; i++) {
const char *arg = argv[i];
if (!strcmp(arg, "--"))
break;
else if (!strcmp(arg, "--cached")) {
add_head(&rev);
break;
}
}
}
for (list = rev.pending_objects; list; list = list->next) {
struct object *obj = list->item;
const char *name = list->name;
int flags = (obj->flags & UNINTERESTING);
if (!obj->parsed)
obj = parse_object(obj->sha1);
obj = deref_tag(obj, NULL, 0);
if (!obj)
die("invalid object '%s' given.", name);
if (!strcmp(obj->type, commit_type))
obj = &((struct commit *)obj)->tree->object;
if (!strcmp(obj->type, tree_type)) {
if (ARRAY_SIZE(ent) <= ents)
die("more than %d trees given: '%s'",
(int) ARRAY_SIZE(ent), name);
obj->flags |= flags;
ent[ents].item = obj;
ent[ents].name = name;
ents++;
continue;
}
if (!strcmp(obj->type, blob_type)) {
if (2 <= blobs)
die("more than two blobs given: '%s'", name);
memcpy(blob[blobs].sha1, obj->sha1, 20);
blob[blobs].name = name;
blobs++;
continue;
}
die("unhandled object '%s' given.", name);
}
if (rev.prune_data) {
const char **pathspec = rev.prune_data;
while (*pathspec) {
if (!path)
path = *pathspec;
paths++;
pathspec++;
}
}
/*
* Now, do the arguments look reasonable?
*/
if (!ents) {
switch (blobs) {
case 0:
return builtin_diff_files(&rev, argc, argv);
break;
case 1:
if (paths != 1)
usage(builtin_diff_usage);
return builtin_diff_b_f(&rev, argc, argv, blob, path);
break;
case 2:
if (paths)
usage(builtin_diff_usage);
return builtin_diff_blobs(&rev, argc, argv, blob);
break;
default:
usage(builtin_diff_usage);
}
}
else if (blobs)
usage(builtin_diff_usage);
else if (ents == 1)
return builtin_diff_index(&rev, argc, argv);
else if (ents == 2)
return builtin_diff_tree(&rev, argc, argv, ent);
else
return builtin_diff_combined(&rev, argc, argv, ent, ents);
usage(builtin_diff_usage);
}

312
builtin-push.c Normal file
View File

@ -0,0 +1,312 @@
/*
* "git push"
*/
#include "cache.h"
#include "refs.h"
#include "run-command.h"
#include "builtin.h"
#define MAX_URI (16)
static const char push_usage[] = "git push [--all] [--tags] [--force] <repository> [<refspec>...]";
static int all = 0, tags = 0, force = 0, thin = 1;
static const char *execute = NULL;
#define BUF_SIZE (2084)
static char buffer[BUF_SIZE];
static const char **refspec = NULL;
static int refspec_nr = 0;
static void add_refspec(const char *ref)
{
int nr = refspec_nr + 1;
refspec = xrealloc(refspec, nr * sizeof(char *));
refspec[nr-1] = ref;
refspec_nr = nr;
}
static int expand_one_ref(const char *ref, const unsigned char *sha1)
{
/* Ignore the "refs/" at the beginning of the refname */
ref += 5;
if (strncmp(ref, "tags/", 5))
return 0;
add_refspec(strdup(ref));
return 0;
}
static void expand_refspecs(void)
{
if (all) {
if (refspec_nr)
die("cannot mix '--all' and a refspec");
/*
* No need to expand "--all" - we'll just use
* the "--all" flag to send-pack
*/
return;
}
if (!tags)
return;
for_each_ref(expand_one_ref);
}
static void set_refspecs(const char **refs, int nr)
{
if (nr) {
size_t bytes = nr * sizeof(char *);
refspec = xrealloc(refspec, bytes);
memcpy(refspec, refs, bytes);
refspec_nr = nr;
}
expand_refspecs();
}
static int get_remotes_uri(const char *repo, const char *uri[MAX_URI])
{
int n = 0;
FILE *f = fopen(git_path("remotes/%s", repo), "r");
int has_explicit_refspec = refspec_nr || all || tags;
if (!f)
return -1;
while (fgets(buffer, BUF_SIZE, f)) {
int is_refspec;
char *s, *p;
if (!strncmp("URL: ", buffer, 5)) {
is_refspec = 0;
s = buffer + 5;
} else if (!strncmp("Push: ", buffer, 6)) {
is_refspec = 1;
s = buffer + 6;
} else
continue;
/* Remove whitespace at the head.. */
while (isspace(*s))
s++;
if (!*s)
continue;
/* ..and at the end */
p = s + strlen(s);
while (isspace(p[-1]))
*--p = 0;
if (!is_refspec) {
if (n < MAX_URI)
uri[n++] = strdup(s);
else
error("more than %d URL's specified, ignoreing the rest", MAX_URI);
}
else if (is_refspec && !has_explicit_refspec)
add_refspec(strdup(s));
}
fclose(f);
if (!n)
die("remote '%s' has no URL", repo);
return n;
}
static const char **config_uri;
static const char *config_repo;
static int config_repo_len;
static int config_current_uri;
static int config_get_refspecs;
static int get_remote_config(const char* key, const char* value)
{
if (!strncmp(key, "remote.", 7) &&
!strncmp(key + 7, config_repo, config_repo_len)) {
if (!strcmp(key + 7 + config_repo_len, ".url")) {
if (config_current_uri < MAX_URI)
config_uri[config_current_uri++] = strdup(value);
else
error("more than %d URL's specified, ignoring the rest", MAX_URI);
}
else if (config_get_refspecs &&
!strcmp(key + 7 + config_repo_len, ".push"))
add_refspec(strdup(value));
}
return 0;
}
static int get_config_remotes_uri(const char *repo, const char *uri[MAX_URI])
{
config_repo_len = strlen(repo);
config_repo = repo;
config_current_uri = 0;
config_uri = uri;
config_get_refspecs = !(refspec_nr || all || tags);
git_config(get_remote_config);
return config_current_uri;
}
static int get_branches_uri(const char *repo, const char *uri[MAX_URI])
{
const char *slash = strchr(repo, '/');
int n = slash ? slash - repo : 1000;
FILE *f = fopen(git_path("branches/%.*s", n, repo), "r");
char *s, *p;
int len;
if (!f)
return 0;
s = fgets(buffer, BUF_SIZE, f);
fclose(f);
if (!s)
return 0;
while (isspace(*s))
s++;
if (!*s)
return 0;
p = s + strlen(s);
while (isspace(p[-1]))
*--p = 0;
len = p - s;
if (slash)
len += strlen(slash);
p = xmalloc(len + 1);
strcpy(p, s);
if (slash)
strcat(p, slash);
uri[0] = p;
return 1;
}
/*
* Read remotes and branches file, fill the push target URI
* list. If there is no command line refspecs, read Push: lines
* to set up the *refspec list as well.
* return the number of push target URIs
*/
static int read_config(const char *repo, const char *uri[MAX_URI])
{
int n;
if (*repo != '/') {
n = get_remotes_uri(repo, uri);
if (n > 0)
return n;
n = get_config_remotes_uri(repo, uri);
if (n > 0)
return n;
n = get_branches_uri(repo, uri);
if (n > 0)
return n;
}
uri[0] = repo;
return 1;
}
static int do_push(const char *repo)
{
const char *uri[MAX_URI];
int i, n;
int remote;
const char **argv;
int argc;
n = read_config(repo, uri);
if (n <= 0)
die("bad repository '%s'", repo);
argv = xmalloc((refspec_nr + 10) * sizeof(char *));
argv[0] = "dummy-send-pack";
argc = 1;
if (all)
argv[argc++] = "--all";
if (force)
argv[argc++] = "--force";
if (execute)
argv[argc++] = execute;
if (thin)
argv[argc++] = "--thin";
remote = argc;
argv[argc++] = "dummy-remote";
while (refspec_nr--)
argv[argc++] = *refspec++;
argv[argc] = NULL;
for (i = 0; i < n; i++) {
int error;
const char *dest = uri[i];
const char *sender = "git-send-pack";
if (!strncmp(dest, "http://", 7) ||
!strncmp(dest, "https://", 8))
sender = "git-http-push";
argv[0] = sender;
argv[remote] = dest;
error = run_command_v(argc, argv);
if (!error)
continue;
switch (error) {
case -ERR_RUN_COMMAND_FORK:
die("unable to fork for %s", sender);
case -ERR_RUN_COMMAND_EXEC:
die("unable to exec %s", sender);
case -ERR_RUN_COMMAND_WAITPID:
case -ERR_RUN_COMMAND_WAITPID_WRONG_PID:
case -ERR_RUN_COMMAND_WAITPID_SIGNAL:
case -ERR_RUN_COMMAND_WAITPID_NOEXIT:
die("%s died with strange error", sender);
default:
return -error;
}
}
return 0;
}
int cmd_push(int argc, const char **argv, char **envp)
{
int i;
const char *repo = "origin"; // default repository
for (i = 1; i < argc; i++) {
const char *arg = argv[i];
if (arg[0] != '-') {
repo = arg;
i++;
break;
}
if (!strcmp(arg, "--all")) {
all = 1;
continue;
}
if (!strcmp(arg, "--tags")) {
tags = 1;
continue;
}
if (!strcmp(arg, "--force")) {
force = 1;
continue;
}
if (!strcmp(arg, "--thin")) {
thin = 1;
continue;
}
if (!strcmp(arg, "--no-thin")) {
thin = 0;
continue;
}
if (!strncmp(arg, "--exec=", 7)) {
execute = arg;
continue;
}
usage(push_usage);
}
set_refspecs(argv + i, argc - i);
return do_push(repo);
}

View File

@ -19,5 +19,9 @@ extern int cmd_version(int argc, const char **argv, char **envp);
extern int cmd_whatchanged(int argc, const char **argv, char **envp);
extern int cmd_show(int argc, const char **argv, char **envp);
extern int cmd_log(int argc, const char **argv, char **envp);
extern int cmd_diff(int argc, const char **argv, char **envp);
extern int cmd_count_objects(int argc, const char **argv, char **envp);
extern int cmd_push(int argc, const char **argv, char **envp);
#endif

View File

@ -169,7 +169,7 @@ extern void rollback_index_file(struct cache_file *);
/* Environment bits from configuration mechanism */
extern int trust_executable_bit;
extern int assume_unchanged;
extern int only_use_symrefs;
extern int prefer_symlink_refs;
extern int warn_ambiguous_refs;
extern int diff_rename_limit_default;
extern int shared_repository;

View File

@ -269,12 +269,16 @@ int main(int argc, char **argv)
/* Check out named files first */
for ( ; i < argc; i++) {
const char *arg = argv[i];
const char *p;
if (all)
die("git-checkout-index: don't mix '--all' and explicit filenames");
if (read_from_stdin)
die("git-checkout-index: don't mix '--stdin' and explicit filenames");
checkout_file(prefix_path(prefix, prefix_length, arg));
p = prefix_path(prefix, prefix_length, arg);
checkout_file(p);
if (p < arg || p > arg + strlen(arg))
free((char*)p);
}
if (read_from_stdin) {
@ -284,6 +288,8 @@ int main(int argc, char **argv)
strbuf_init(&buf);
while (1) {
char *path_name;
const char *p;
read_line(&buf, stdin, line_termination);
if (buf.eof)
break;
@ -291,7 +297,10 @@ int main(int argc, char **argv)
path_name = unquote_c_style(buf.buf, NULL);
else
path_name = buf.buf;
checkout_file(prefix_path(prefix, prefix_length, path_name));
p = prefix_path(prefix, prefix_length, path_name);
checkout_file(p);
if (p < path_name || p > path_name + strlen(path_name))
free((char *)p);
if (path_name != buf.buf)
free(path_name);
}

View File

@ -831,15 +831,16 @@ void show_combined_diff(struct combine_diff_path *p,
}
}
void diff_tree_combined_merge(const unsigned char *sha1,
int dense, struct rev_info *rev)
void diff_tree_combined(const unsigned char *sha1,
const unsigned char parent[][20],
int num_parent,
int dense,
struct rev_info *rev)
{
struct diff_options *opt = &rev->diffopt;
struct commit *commit = lookup_commit(sha1);
struct diff_options diffopts;
struct commit_list *parents;
struct combine_diff_path *p, *paths = NULL;
int num_parent, i, num_paths;
int i, num_paths;
int do_diffstat;
do_diffstat = (opt->output_format == DIFF_FORMAT_DIFFSTAT ||
@ -849,17 +850,8 @@ void diff_tree_combined_merge(const unsigned char *sha1,
diffopts.with_stat = 0;
diffopts.recursive = 1;
/* count parents */
for (parents = commit->parents, num_parent = 0;
parents;
parents = parents->next, num_parent++)
; /* nothing */
/* find set of paths that everybody touches */
for (parents = commit->parents, i = 0;
parents;
parents = parents->next, i++) {
struct commit *parent = parents->item;
for (i = 0; i < num_parent; i++) {
/* show stat against the first parent even
* when doing combined diff.
*/
@ -867,8 +859,7 @@ void diff_tree_combined_merge(const unsigned char *sha1,
diffopts.output_format = DIFF_FORMAT_DIFFSTAT;
else
diffopts.output_format = DIFF_FORMAT_NO_OUTPUT;
diff_tree_sha1(parent->object.sha1, commit->object.sha1, "",
&diffopts);
diff_tree_sha1(parent[i], sha1, "", &diffopts);
diffcore_std(&diffopts);
paths = intersect_paths(paths, i, num_parent);
@ -907,3 +898,25 @@ void diff_tree_combined_merge(const unsigned char *sha1,
free(tmp);
}
}
void diff_tree_combined_merge(const unsigned char *sha1,
int dense, struct rev_info *rev)
{
int num_parent;
const unsigned char (*parent)[20];
struct commit *commit = lookup_commit(sha1);
struct commit_list *parents;
/* count parents */
for (parents = commit->parents, num_parent = 0;
parents;
parents = parents->next, num_parent++)
; /* nothing */
parent = xmalloc(num_parent * sizeof(*parent));
for (parents = commit->parents, num_parent = 0;
parents;
parents = parents->next, num_parent++)
memcpy(parent + num_parent, parents->item->object.sha1, 20);
diff_tree_combined(sha1, parent, num_parent, dense, rev);
}

View File

@ -227,8 +227,8 @@ 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);
if (!strcmp(var, "core.prefersymlinkrefs")) {
prefer_symlink_refs = git_config_bool(var, value);
return 0;
}
@ -335,8 +335,11 @@ static int store_aux(const char* key, const char* 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;
} else if (strrchr(key, '.') - key == store.baselen &&
!strncmp(key, store.key, store.baselen)) {
store.state = SECTION_SEEN;
store.offset[store.seen] = ftell(config_file);
}
}
return 0;
}

View File

@ -8,7 +8,7 @@ use vars qw/ $AUTHOR $VERSION
$GIT_SVN_INDEX $GIT_SVN
$GIT_DIR $REV_DIR/;
$AUTHOR = 'Eric Wong <normalperson@yhbt.net>';
$VERSION = '0.11.0';
$VERSION = '1.0.0';
use Cwd qw/abs_path/;
$GIT_DIR = abs_path($ENV{GIT_DIR} || '.git');
@ -42,7 +42,8 @@ my %fc_opts = ( 'no-ignore-externals' => \$_no_ignore_ext,
my %cmd = (
fetch => [ \&fetch, "Download new revisions from SVN",
{ 'revision|r=s' => \$_revision, %fc_opts } ],
init => [ \&init, "Initialize and fetch (import)", { } ],
init => [ \&init, "Initialize a repo for tracking" .
" (requires URL argument)", { } ],
commit => [ \&commit, "Commit git revisions to SVN",
{ 'stdin|' => \$_stdin,
'edit|e' => \$_edit,
@ -220,7 +221,8 @@ when you have upgraded your tools and habits to use refs/remotes/$GIT_SVN
}
sub init {
$SVN_URL = shift or croak "SVN repository location required\n";
$SVN_URL = shift or die "SVN repository location required " .
"as a command-line argument\n";
unless (-d $GIT_DIR) {
sys('git-init-db');
}

View File

@ -36,17 +36,22 @@ COMMANDS
--------
init::
Creates an empty git repository with additional metadata
directories for git-svn. The SVN_URL must be specified
at this point.
directories for git-svn. The Subversion URL must be specified
as a command-line argument.
fetch::
Fetch unfetched revisions from the SVN_URL we are tracking.
refs/heads/remotes/git-svn will be updated to the latest revision.
Fetch unfetched revisions from the Subversion URL we are
tracking. refs/remotes/git-svn will be updated to the
latest revision.
Note: You should never attempt to modify the remotes/git-svn branch
outside of git-svn. Instead, create a branch from remotes/git-svn
and work on that branch. Use the 'commit' command (see below)
to write git commits back to remotes/git-svn.
Note: You should never attempt to modify the remotes/git-svn
branch outside of git-svn. Instead, create a branch from
remotes/git-svn and work on that branch. Use the 'commit'
command (see below) to write git commits back to
remotes/git-svn.
See 'Additional Fetch Arguments' if you are interested in
manually joining branches on commit.
commit::
Commit specified commit or tree objects to SVN. This relies on
@ -62,9 +67,9 @@ rebuild::
tracked with git-svn. Unfortunately, git-clone does not clone
git-svn metadata and the svn working tree that git-svn uses for
its operations. This rebuilds the metadata so git-svn can
resume fetch operations. SVN_URL may be optionally specified if
the directory/repository you're tracking has moved or changed
protocols.
resume fetch operations. A Subversion URL may be optionally
specified at the command-line if the directory/repository you're
tracking has moved or changed protocols.
show-ignore::
Recursively finds and lists the svn:ignore property on
@ -123,6 +128,24 @@ OPTIONS
repo-config key: svn.l
repo-config key: svn.findcopiesharder
-A<filename>::
--authors-file=<filename>::
Syntax is compatible with the files used by git-svnimport and
git-cvsimport:
------------------------------------------------------------------------
loginname = Joe User <user@example.com>
------------------------------------------------------------------------
If this option is specified and git-svn encounters an SVN
committer name that does not exist in the authors-file, git-svn
will abort operation. The user will then have to add the
appropriate entry. Re-running the previous git-svn command
after the authors-file is modified should continue operation.
repo-config key: svn.authors-file
ADVANCED OPTIONS
----------------
-b<refname>::

View File

@ -2,11 +2,11 @@
#define DELTA_H
/* handling of delta buffers */
extern void *diff_delta(void *from_buf, unsigned long from_size,
void *to_buf, unsigned long to_size,
extern void *diff_delta(const void *from_buf, unsigned long from_size,
const void *to_buf, unsigned long to_size,
unsigned long *delta_size, unsigned long max_size);
extern void *patch_delta(void *src_buf, unsigned long src_size,
void *delta_buf, unsigned long delta_size,
const void *delta_buf, unsigned long delta_size,
unsigned long *dst_size);
/* the smallest possible delta size is 4 bytes */

View File

@ -131,8 +131,8 @@ static struct index ** delta_index(const unsigned char *buf,
/* the maximum size for any opcode */
#define MAX_OP_SIZE COPYOP_SIZE(0xffffffff, 0xffffffff)
void *diff_delta(void *from_buf, unsigned long from_size,
void *to_buf, unsigned long to_size,
void *diff_delta(const void *from_buf, unsigned long from_size,
const void *to_buf, unsigned long to_size,
unsigned long *delta_size,
unsigned long max_size)
{

6
diff.c
View File

@ -1018,14 +1018,12 @@ static void run_diff(struct diff_filepair *p, struct diff_options *o)
}
if (memcmp(one->sha1, two->sha1, 20)) {
char one_sha1[41];
int abbrev = o->full_index ? 40 : DEFAULT_ABBREV;
memcpy(one_sha1, sha1_to_hex(one->sha1), 41);
len += snprintf(msg + len, sizeof(msg) - len,
"index %.*s..%.*s",
abbrev, one_sha1, abbrev,
sha1_to_hex(two->sha1));
abbrev, sha1_to_hex(one->sha1),
abbrev, sha1_to_hex(two->sha1));
if (one->mode == two->mode)
len += snprintf(msg + len, sizeof(msg) - len,
" %06o", one->mode);

2
diff.h
View File

@ -75,6 +75,8 @@ struct combine_diff_path {
extern void show_combined_diff(struct combine_diff_path *elem, int num_parent,
int dense, struct rev_info *);
extern void diff_tree_combined(const unsigned char *sha1, const unsigned char parent[][20], int num_parent, int dense, struct rev_info *rev);
extern void diff_tree_combined_merge(const unsigned char *sha1, int, struct rev_info *);
extern void diff_addremove(struct diff_options *,

View File

@ -13,7 +13,7 @@ char git_default_email[MAX_GITNAME];
char git_default_name[MAX_GITNAME];
int trust_executable_bit = 1;
int assume_unchanged = 0;
int only_use_symrefs = 0;
int prefer_symlink_refs = 0;
int warn_ambiguous_refs = 1;
int repository_format_version = 0;
char git_commit_encoding[MAX_ENCODING_LENGTH] = "utf-8";

View File

@ -1,31 +0,0 @@
#!/bin/sh
#
# Copyright (c) 2005 Junio C Hamano
#
GIT_DIR=`git-rev-parse --git-dir` || exit $?
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
# "no-such" is to help Darwin folks by not using xargs -r.
find "$GIT_DIR/objects"/?? -type f -print 2>/dev/null |
xargs du -k "$GIT_DIR/objects/no-such" 2>/dev/null |
sed -e 's/[ ].*/ +/'
echo p
} | dc) kilobytes

View File

@ -1,74 +0,0 @@
#!/bin/sh
#
# Copyright (c) 2005 Linus Torvalds
# Copyright (c) 2005 Junio C Hamano
USAGE='[ --diff-options ] <ent>{0,2} [<path>...]'
SUBDIRECTORY_OK='Yes'
. git-sh-setup
rev=$(git-rev-parse --revs-only --no-flags --sq "$@") || exit
flags=$(git-rev-parse --no-revs --flags --sq "$@")
files=$(git-rev-parse --no-revs --no-flags --sq "$@")
# I often say 'git diff --cached -p' and get scolded by git-diff-files, but
# obviously I mean 'git diff --cached -p HEAD' in that case.
case "$rev" in
'')
case " $flags " in
*" '--cached' "*)
rev='HEAD '
;;
esac
esac
# If we have -[123] --ours --theirs --base, don't do --cc by default.
case " $flags " in
*" '-"[123]"' "* | *" '--ours' "* | *" '--base' "* | *" '--theirs' "*)
cc_or_p=-p ;;
*)
cc_or_p=--cc ;;
esac
# If we do not have --name-status, --name-only, -r, -c or --stat,
# default to --cc.
case " $flags " in
*" '--name-status' "* | *" '--name-only' "* | *" '-r' "* | *" '-c' "* | \
*" '--stat' "*)
;;
*)
flags="$flags'$cc_or_p' " ;;
esac
# If we do not have -B, -C, -r, nor -p, default to -M.
case " $flags " in
*" '-"[BCMrp]* | *" '--find-copies-harder' "*)
;; # something like -M50.
*)
flags="$flags'-M' " ;;
esac
case "$rev" in
?*' '?*' '?*)
usage
;;
?*' '^?*)
begin=$(expr "$rev" : '.*^.\([0-9a-f]*\).*') &&
end=$(expr "$rev" : '.\([0-9a-f]*\). .*') || exit
cmd="git-diff-tree $flags $begin $end -- $files"
;;
?*' '?*)
cmd="git-diff-tree $flags $rev -- $files"
;;
?*' ')
cmd="git-diff-index $flags $rev -- $files"
;;
'')
cmd="git-diff-files $flags -- $files"
;;
*)
usage
;;
esac
eval "$cmd"

View File

@ -1,28 +0,0 @@
#!/bin/sh
USAGE='[-p] [--max-count=<n>] [<since>..<limit>] [--pretty=<format>] [-m] [git-diff-tree options] [git-rev-list options]'
SUBDIRECTORY_OK='Yes'
. git-sh-setup
diff_tree_flags=$(git-rev-parse --sq --no-revs --flags "$@") || exit
case "$0" in
*whatchanged)
count=
test -z "$diff_tree_flags" &&
diff_tree_flags=$(git-repo-config --get whatchanged.difftree)
diff_tree_default_flags='-c -M --abbrev' ;;
*show)
count=-n1
test -z "$diff_tree_flags" &&
diff_tree_flags=$(git-repo-config --get show.difftree)
diff_tree_default_flags='--cc --always' ;;
esac
test -z "$diff_tree_flags" &&
diff_tree_flags="$diff_tree_default_flags"
rev_list_args=$(git-rev-parse --sq --default HEAD --revs-only "$@") &&
diff_tree_args=$(git-rev-parse --sq --no-revs --no-flags "$@") &&
eval "git-rev-list $count $rev_list_args" |
eval "git-diff-tree --stdin --pretty -r $diff_tree_flags $diff_tree_args" |
LESS="$LESS -S" ${PAGER:-less}

3
git.c
View File

@ -46,6 +46,9 @@ static void handle_internal_command(int argc, const char **argv, char **envp)
{ "log", cmd_log },
{ "whatchanged", cmd_whatchanged },
{ "show", cmd_show },
{ "push", cmd_push },
{ "count-objects", cmd_count_objects },
{ "diff", cmd_diff },
};
int i;

1777
gitk

File diff suppressed because it is too large Load Diff

View File

@ -3,6 +3,15 @@
#include "commit.h"
#include "log-tree.h"
static void show_parents(struct commit *commit, int abbrev)
{
struct commit_list *p;
for (p = commit->parents; p ; p = p->next) {
struct commit *parent = p->item;
printf(" %s", diff_unique_abbrev(parent->object.sha1, abbrev));
}
}
void show_log(struct rev_info *opt, struct log_info *log, const char *sep)
{
static char this_header[16384];
@ -14,7 +23,10 @@ void show_log(struct rev_info *opt, struct log_info *log, const char *sep)
opt->loginfo = NULL;
if (!opt->verbose_header) {
puts(sha1_to_hex(commit->object.sha1));
fputs(diff_unique_abbrev(commit->object.sha1, abbrev_commit), stdout);
if (opt->parents)
show_parents(commit, abbrev_commit);
putchar('\n');
return;
}
@ -40,7 +52,9 @@ void show_log(struct rev_info *opt, struct log_info *log, const char *sep)
printf("%s%s",
opt->commit_format == CMIT_FMT_ONELINE ? "" : "commit ",
diff_unique_abbrev(commit->object.sha1, abbrev_commit));
if (parent)
if (opt->parents)
show_parents(commit, abbrev_commit);
if (parent)
printf(" (from %s)", diff_unique_abbrev(parent->object.sha1, abbrev_commit));
putchar(opt->commit_format == CMIT_FMT_ONELINE ? ' ' : '\n');

View File

@ -24,16 +24,14 @@ static const char *sha1_to_hex_zero(const unsigned char *sha1)
static void resolve(const char *base, struct name_entry *branch1, struct name_entry *result)
{
char branch1_sha1[50];
/* If it's already branch1, don't bother showing it */
if (!branch1)
return;
memcpy(branch1_sha1, sha1_to_hex_zero(branch1->sha1), 41);
printf("0 %06o->%06o %s->%s %s%s\n",
branch1->mode, result->mode,
branch1_sha1, sha1_to_hex_zero(result->sha1),
sha1_to_hex_zero(branch1->sha1),
sha1_to_hex_zero(result->sha1),
base, result->path);
}

View File

@ -1239,6 +1239,7 @@ int main(int argc, char **argv)
setup_git_directory();
progress = isatty(2);
for (i = 1; i < argc; i++) {
const char *arg = argv[i];
@ -1269,6 +1270,10 @@ int main(int argc, char **argv)
usage(pack_usage);
continue;
}
if (!strcmp("--progress", arg)) {
progress = 1;
continue;
}
if (!strcmp("-q", arg)) {
progress = 0;
continue;

View File

@ -14,7 +14,7 @@
#include "delta.h"
void *patch_delta(void *src_buf, unsigned long src_size,
void *delta_buf, unsigned long delta_size,
const void *delta_buf, unsigned long delta_size,
unsigned long *dst_size)
{
const unsigned char *data, *top;

4
refs.c
View File

@ -76,8 +76,8 @@ int create_symref(const char *git_HEAD, const char *refs_heads_master)
char ref[1000];
int fd, len, written;
#ifdef USE_SYMLINK_HEAD
if (!only_use_symrefs) {
#ifndef NO_SYMLINK_HEAD
if (prefer_symlink_refs) {
unlink(git_HEAD);
if (!symlink(refs_heads_master, git_HEAD))
return 0;

View File

@ -2,11 +2,13 @@
#include <regex.h>
static const char git_config_set_usage[] =
"git-repo-config [ --bool | --int ] [--get | --get-all | --replace-all | --unset | --unset-all] name [value [value_regex]] | --list";
"git-repo-config [ --bool | --int ] [--get | --get-all | --get-regexp | --replace-all | --unset | --unset-all] name [value [value_regex]] | --list";
static char* key = NULL;
static char* value = NULL;
static regex_t* key_regexp = NULL;
static regex_t* regexp = NULL;
static int show_keys = 0;
static int use_key_regexp = 0;
static int do_all = 0;
static int do_not_match = 0;
static int seen = 0;
@ -23,34 +25,40 @@ static int show_all_config(const char *key_, const char *value_)
static int show_config(const char* key_, const char* value_)
{
char value[256];
const char *vptr = value;
int dup_error = 0;
if (value_ == NULL)
value_ = "";
if (!strcmp(key_, key) &&
(regexp == NULL ||
if (!use_key_regexp && strcmp(key_, key))
return 0;
if (use_key_regexp && regexec(key_regexp, key_, 0, NULL, 0))
return 0;
if (regexp != NULL &&
(do_not_match ^
!regexec(regexp, value_, 0, NULL, 0)))) {
if (do_all) {
printf("%s\n", value_);
return 0;
}
if (seen > 0) {
fprintf(stderr, "More than one value: %s\n", value);
free(value);
}
regexec(regexp, value_, 0, NULL, 0)))
return 0;
if (type == T_INT) {
value = malloc(256);
sprintf(value, "%d", git_config_int(key_, value_));
} else if (type == T_BOOL) {
value = malloc(256);
sprintf(value, "%s", git_config_bool(key_, value_)
? "true" : "false");
} else {
value = strdup(value_);
}
seen++;
if (show_keys)
printf("%s ", key_);
if (seen && !do_all)
dup_error = 1;
if (type == T_INT)
sprintf(value, "%d", git_config_int(key_, value_));
else if (type == T_BOOL)
vptr = git_config_bool(key_, value_) ? "true" : "false";
else
vptr = value_;
seen++;
if (dup_error) {
error("More than one value for the key %s: %s",
key_, vptr);
}
else
printf("%s\n", vptr);
return 0;
}
@ -63,6 +71,14 @@ static int get_value(const char* key_, const char* regex_)
key[i] = tolower(key_[i]);
key[i] = 0;
if (use_key_regexp) {
key_regexp = (regex_t*)malloc(sizeof(regex_t));
if (regcomp(key_regexp, key, REG_EXTENDED)) {
fprintf(stderr, "Invalid key pattern: %s\n", key_);
return -1;
}
}
if (regex_) {
if (regex_[0] == '!') {
do_not_match = 1;
@ -77,10 +93,6 @@ static int get_value(const char* key_, const char* regex_)
}
git_config(show_config);
if (value) {
printf("%s\n", value);
free(value);
}
free(key);
if (regexp) {
regfree(regexp);
@ -88,9 +100,9 @@ static int get_value(const char* key_, const char* regex_)
}
if (do_all)
return 0;
return !seen;
return seen == 1 ? 0 : 1;
return (seen == 1) ? 0 : 1;
}
int main(int argc, const char **argv)
@ -123,6 +135,11 @@ int main(int argc, const char **argv)
else if (!strcmp(argv[1], "--get-all")) {
do_all = 1;
return get_value(argv[2], NULL);
} else if (!strcmp(argv[1], "--get-regexp")) {
show_keys = 1;
use_key_regexp = 1;
do_all = 1;
return get_value(argv[2], NULL);
} else
return git_config_set(argv[1], argv[2]);
@ -136,6 +153,11 @@ int main(int argc, const char **argv)
else if (!strcmp(argv[1], "--get-all")) {
do_all = 1;
return get_value(argv[2], argv[3]);
} else if (!strcmp(argv[1], "--get-regexp")) {
show_keys = 1;
use_key_regexp = 1;
do_all = 1;
return get_value(argv[2], argv[3]);
} else if (!strcmp(argv[1], "--replace-all"))
return git_config_set_multivar(argv[2], argv[3], NULL, 1);

View File

@ -574,7 +574,7 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
revs->max_count = atoi(arg + 12);
continue;
}
/* accept -<digit>, like traditilnal "head" */
/* accept -<digit>, like traditional "head" */
if ((*arg == '-') && isdigit(arg[1])) {
revs->max_count = atoi(arg + 1);
continue;
@ -694,6 +694,7 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
}
if (!strcmp(arg, "-c")) {
revs->diff = 1;
revs->dense_combined_merges = 0;
revs->combine_merges = 1;
continue;
}

View File

@ -108,9 +108,10 @@ int safe_create_leading_directories(char *path)
char * sha1_to_hex(const unsigned char *sha1)
{
static char buffer[50];
static int bufno;
static char hexbuffer[4][50];
static const char hex[] = "0123456789abcdef";
char *buf = buffer;
char *buffer = hexbuffer[3 & ++bufno], *buf = buffer;
int i;
for (i = 0; i < 20; i++) {

View File

@ -5,7 +5,7 @@
#include "refs.h"
static const char show_branch_usage[] =
"git-show-branch [--current] [--all] [--heads] [--tags] [--topo-order] [--more=count | --list | --independent | --merge-base ] [--topics] [<refs>...]";
"git-show-branch [--dense] [--current] [--all] [--heads] [--tags] [--topo-order] [--more=count | --list | --independent | --merge-base ] [--topics] [<refs>...]";
static int default_num = 0;
static int default_alloc = 0;
@ -527,6 +527,27 @@ static int git_show_branch_config(const char *var, const char *value)
return git_default_config(var, value);
}
static int omit_in_dense(struct commit *commit, struct commit **rev, int n)
{
/* If the commit is tip of the named branches, do not
* omit it.
* Otherwise, if it is a merge that is reachable from only one
* tip, it is not that interesting.
*/
int i, flag, count;
for (i = 0; i < n; i++)
if (rev[i] == commit)
return 0;
flag = commit->object.flags;
for (i = count = 0; i < n; i++) {
if (flag & (1u << (i + REV_SHIFT)))
count++;
}
if (count == 1)
return 1;
return 0;
}
int main(int ac, char **av)
{
struct commit *rev[MAX_REVS], *commit;
@ -548,6 +569,7 @@ int main(int ac, char **av)
int with_current_branch = 0;
int head_at = -1;
int topics = 0;
int dense = 1;
setup_git_directory();
git_config(git_show_branch_config);
@ -590,6 +612,8 @@ int main(int ac, char **av)
lifo = 1;
else if (!strcmp(arg, "--topics"))
topics = 1;
else if (!strcmp(arg, "--sparse"))
dense = 0;
else if (!strcmp(arg, "--date-order"))
lifo = 0;
else
@ -732,12 +756,15 @@ int main(int ac, char **av)
shown_merge_point |= is_merge_point;
if (1 < num_rev) {
int is_merge = !!(commit->parents && commit->parents->next);
int is_merge = !!(commit->parents &&
commit->parents->next);
if (topics &&
!is_merge_point &&
(this_flag & (1u << REV_SHIFT)))
continue;
if (dense && is_merge &&
omit_in_dense(commit, rev, num_rev))
continue;
for (i = 0; i < num_rev; i++) {
int mark;
if (!(this_flag & (1u << (i + REV_SHIFT))))

View File

@ -247,6 +247,24 @@ EOF
test_expect_success 'hierarchical section value' 'cmp .git/config expect'
cat > expect << EOF
beta.noindent=sillyValue
nextsection.nonewline=wow2 for me
123456.a123=987
1.2.3.alpha=beta
EOF
test_expect_success 'working --list' \
'git-repo-config --list > output && cmp output expect'
cat > expect << EOF
beta.noindent sillyValue
nextsection.nonewline wow2 for me
EOF
test_expect_success '--get-regexp' \
'git-repo-config --get-regexp in > output && cmp output expect'
cat > .git/config << EOF
[novalue]
variable
@ -255,5 +273,41 @@ EOF
test_expect_success 'get variable with no value' \
'git-repo-config --get novalue.variable ^$'
git-repo-config > output 2>&1
test_expect_success 'no arguments, but no crash' \
"test $? = 129 && grep usage output"
cat > .git/config << EOF
[a.b]
c = d
EOF
git-repo-config a.x y
cat > expect << EOF
[a.b]
c = d
[a]
x = y
EOF
test_expect_success 'new section is partial match of another' 'cmp .git/config expect'
git-repo-config b.x y
git-repo-config a.b c
cat > expect << EOF
[a.b]
c = d
[a]
x = y
b = c
[b]
x = y
EOF
test_expect_success 'new variable inserts into proper section' 'cmp .git/config expect'
test_done

View File

@ -364,23 +364,26 @@ static void update_one(const char *path, const char *prefix, int prefix_length)
const char *p = prefix_path(prefix, prefix_length, path);
if (!verify_path(p)) {
fprintf(stderr, "Ignoring path %s\n", path);
return;
goto free_return;
}
if (mark_valid_only) {
if (mark_valid(p))
die("Unable to mark file %s", path);
return;
goto free_return;
}
if (force_remove) {
if (remove_file_from_cache(p))
die("git-update-index: unable to remove %s", path);
report("remove '%s'", path);
return;
goto free_return;
}
if (add_file_to_cache(p))
die("Unable to process file %s", path);
report("add '%s'", path);
free_return:
if (p < path || p > path + strlen(path))
free((char*)p);
}
static void read_index_info(int line_termination)
@ -473,7 +476,7 @@ static void read_index_info(int line_termination)
}
static const char update_index_usage[] =
"git-update-index [-q] [--add] [--replace] [--remove] [--unmerged] [--refresh] [--cacheinfo] [--chmod=(+|-)x] [--info-only] [--force-remove] [--stdin] [--index-info] [--ignore-missing] [-z] [--verbose] [--] <file>...";
"git-update-index [-q] [--add] [--replace] [--remove] [--unmerged] [--refresh] [--really-refresh] [--cacheinfo] [--chmod=(+|-)x] [--assume-unchanged] [--info-only] [--force-remove] [--stdin] [--index-info] [--unresolve] [--ignore-missing] [-z] [--verbose] [--] <file>...";
static unsigned char head_sha1[20];
static unsigned char merge_head_sha1[20];
@ -576,7 +579,8 @@ static void read_head_pointers(void)
}
}
static int do_unresolve(int ac, const char **av)
static int do_unresolve(int ac, const char **av,
const char *prefix, int prefix_length)
{
int i;
int err = 0;
@ -588,7 +592,10 @@ static int do_unresolve(int ac, const char **av)
for (i = 1; i < ac; i++) {
const char *arg = av[i];
err |= unresolve_one(arg);
const char *p = prefix_path(prefix, prefix_length, arg);
err |= unresolve_one(p);
if (p < arg || p > arg + strlen(arg))
free((char*)p);
}
return err;
}
@ -704,7 +711,8 @@ int main(int argc, const char **argv)
break;
}
if (!strcmp(path, "--unresolve")) {
has_errors = do_unresolve(argc - i, argv + i);
has_errors = do_unresolve(argc - i, argv + i,
prefix, prefix_length);
if (has_errors)
active_cache_changed = 0;
goto finish;
@ -730,6 +738,7 @@ int main(int argc, const char **argv)
strbuf_init(&buf);
while (1) {
char *path_name;
const char *p;
read_line(&buf, stdin, line_termination);
if (buf.eof)
break;
@ -737,11 +746,12 @@ int main(int argc, const char **argv)
path_name = unquote_c_style(buf.buf, NULL);
else
path_name = buf.buf;
update_one(path_name, prefix, prefix_length);
if (set_executable_bit) {
const char *p = prefix_path(prefix, prefix_length, path_name);
p = prefix_path(prefix, prefix_length, path_name);
update_one(p, NULL, 0);
if (set_executable_bit)
chmod_path(set_executable_bit, p);
}
if (p < path_name || p > path_name + strlen(path_name))
free((char*) p);
if (path_name != buf.buf)
free(path_name);
}