Merge branch 'master' of git://repo.or.cz/alt-git

This commit is contained in:
Johannes Sixt
2007-08-29 13:08:45 +02:00
74 changed files with 1797 additions and 469 deletions

View File

@@ -28,7 +28,7 @@ Updates since v1.5.2
* For people who need to import from Perforce, a front-end for
fast-import is in contrib/fast-import/.
* Comes with git-gui 0.8.0.
* Comes with git-gui 0.8.2.
* Comes with updated gitk.
@@ -130,6 +130,9 @@ Updates since v1.5.2
- "git init -q" makes the command quieter.
- "git -p command" now has a cousin of opposite sex, "git --no-pager
command".
* Updated behavior of existing commands.
- "gitweb" can offer multiple snapshot formats.
@@ -172,6 +175,15 @@ Updates since v1.5.2
- "git log" learned --log-size to show the number of bytes in
the log message part of the output to help qgit.
- "git log --name-status" does not require you to give "-r" anymore.
As a general rule, Porcelain commands should recurse when showing
diff.
- "git format-patch --root A" can be used to format everything
since the beginning up to A. This was supported with
"git format-patch --root A A" for a long time, but was not
properly documented.
- "git svn dcommit" retains local merge information.
- "git svnimport" allows an empty string to be specified as the
@@ -301,8 +313,8 @@ Updates since v1.5.2
when switching branches that have differences in only a
handful paths.
- "git commit paths..." has also been optimized.
- "git add paths..." and "git commit paths..." has also been
heavily optimized.
Fixes since v1.5.2
------------------
@@ -315,8 +327,14 @@ this release, unless otherwise noted.
- "gitweb" had trouble handling non UTF-8 text with older
Encode.pm Perl module.
- "git-write-tree" had a bad interaction with racy-git avoidance and
gitattributes mechanisms.
- "git --bare command" overrode existing GIT_DIR setting and always
made it treat the current working directory as GIT_DIR.
--
exec >/var/tmp/1
O=v1.5.3-rc4
O=v1.5.3-rc7
echo O=`git describe refs/heads/master`
git shortlog --no-merges $O..refs/heads/master ^refs/heads/maint

View File

@@ -192,7 +192,7 @@ core.worktree::
variable and the '--work-tree' command line option.
core.logAllRefUpdates::
Updates to a ref <ref> is logged to the file
Enable the reflog. Updates to a ref <ref> is logged to the file
"$GIT_DIR/logs/<ref>", by appending the new and old
SHA1, the date/time and the reason of the update, but
only when the file exists. If this configuration
@@ -283,7 +283,7 @@ core.excludesfile::
core.editor::
Commands such as `commit` and `tag` that lets you edit
messages by lauching an editor uses the value of this
messages by launching an editor uses the value of this
variable when it is set, and the environment variable
`GIT_EDITOR` is not set. The order of preference is
`GIT_EDITOR` environment, `core.editor`, `VISUAL` and
@@ -465,11 +465,11 @@ rerere.enabled::
be encountered again. See gitlink:git-rerere[1].
gitcvs.enabled::
Whether the cvs server interface is enabled for this repository.
Whether the CVS server interface is enabled for this repository.
See gitlink:git-cvsserver[1].
gitcvs.logfile::
Path to a log file where the cvs server interface well... logs
Path to a log file where the CVS server interface well... logs
various stuff. See gitlink:git-cvsserver[1].
gitcvs.allbinary::
@@ -500,10 +500,10 @@ gitcvs.dbuser, gitcvs.dbpass::
'gitcvs.dbuser' supports variable substitution (see
gitlink:git-cvsserver[1] for details).
All gitcvs variables except for 'gitcvs.allbinary' can also specifed
as 'gitcvs.<access_method>.<varname>' (where 'access_method' is one
of "ext" and "pserver") to make them apply only for the given access
method.
All gitcvs variables except for 'gitcvs.allbinary' can also be
specified as 'gitcvs.<access_method>.<varname>' (where 'access_method'
is one of "ext" and "pserver") to make them apply only for the given
access method.
http.sslVerify::
Whether to verify the SSL certificate when fetching or pushing
@@ -615,7 +615,7 @@ pack.compression::
not set, defaults to -1.
pack.deltaCacheSize::
The maxium memory in bytes used for caching deltas in
The maximum memory in bytes used for caching deltas in
gitlink:git-pack-objects[1].
A value of 0 means no limit. Defaults to 0.
@@ -675,15 +675,11 @@ showbranch.default::
See gitlink:git-show-branch[1].
tar.umask::
By default, gitlink:git-tar-tree[1] sets file and directories modes
to 0666 or 0777. While this is both useful and acceptable for projects
such as the Linux Kernel, it might be excessive for other projects.
With this variable, it becomes possible to tell
gitlink:git-tar-tree[1] to apply a specific umask to the modes above.
The special value "user" indicates that the user's current umask will
be used. This should be enough for most projects, as it will lead to
the same permissions as gitlink:git-checkout[1] would use. The default
value remains 0, which means world read-write.
This variable can be used to restrict the permission bits of
tar archive entries. The default is 0002, which turns off the
world write bit. The special value "user" indicates that the
archiving user's umask will be used instead. See umask(2) and
gitlink:git-archive[1].
user.email::
Your email address to be recorded in any newly created commits.

View File

@@ -7,7 +7,9 @@ git-add - Add file contents to the index
SYNOPSIS
--------
'git-add' [-n] [-v] [-f] [--interactive | -i] [-u] [--refresh] [--] <file>...
[verse]
'git-add' [-n] [-v] [-f] [--interactive | -i] [-u] [--refresh]
[--] <filepattern>...
DESCRIPTION
-----------
@@ -31,9 +33,9 @@ files have changes that are staged for the next commit.
The 'git add' command will not add ignored files by default. If any
ignored files were explicitly specified on the command line, 'git add'
will fail with a list of ignored files. Ignored files reached by
directory recursion or filename globbing will be silently ignored.
The 'add' command can be used to add ignored files with the `-f`
(force) option.
directory recursion or filename globbing performed by Git (quote your
globs before the shell) will be silently ignored. The 'add' command can
be used to add ignored files with the `-f` (force) option.
Please see gitlink:git-commit[1] for alternative ways to add content to a
commit.
@@ -41,7 +43,7 @@ commit.
OPTIONS
-------
<file>...::
<filepattern>...::
Files to add content from. Fileglobs (e.g. `*.c`) can
be given to add all matching files. Also a
leading directory name (e.g. `dir` to add `dir/file1`

View File

@@ -72,16 +72,13 @@ zip
CONFIGURATION
-------------
By default, file and directories modes are set to 0666 or 0777 in tar
archives. It is possible to change this by setting the "umask" variable
in the repository configuration as follows :
[tar]
umask = 002 ;# group friendly
The special umask value "user" indicates that the user's current umask
will be used instead. The default value remains 0, which means world
readable/writable files and directories.
tar.umask::
This variable can be used to restrict the permission bits of
tar archive entries. The default is 0002, which turns off the
world write bit. The special value "user" indicates that the
archiving user's umask will be used instead. See umask(2) for
details.
EXAMPLES
--------

View File

@@ -35,7 +35,7 @@ working tree.
OPTIONS
-------
-q::
Quiet, supress feedback messages.
Quiet, suppress feedback messages.
-f::
Proceed even if the index or the working tree differs

View File

@@ -51,9 +51,9 @@ A commit encapsulates:
- author name, email and date
- committer name and email and the commit time.
If not provided, "git-commit-tree" uses your name, hostname and domain to
provide author and committer info. This can be overridden by
either `.git/config` file, or using the following environment variables.
While parent object ids are provided on the command line, author and
committer information is taken from the following environment variables,
if set:
GIT_AUTHOR_NAME
GIT_AUTHOR_EMAIL
@@ -65,12 +65,9 @@ either `.git/config` file, or using the following environment variables.
(nb "<", ">" and "\n"s are stripped)
In `.git/config` file, the following items are used for GIT_AUTHOR_NAME and
GIT_AUTHOR_EMAIL:
[user]
name = "Your Name"
email = "your@email.address.xz"
In case (some of) these environment variables are not set, the information
is taken from the configuration items user.name and user.email, or, if not
present, system user name and fully qualified hostname.
A commit comment is read from stdin. If a changelog
entry is not provided via "<" redirection, "git-commit-tree" will just wait

View File

@@ -139,7 +139,7 @@ See also <<FILES>>.
FILES
-----
If not set explicitely with '--file', there are three files where
If not set explicitly with '--file', there are three files where
git-config will search for configuration options:
.git/config::

View File

@@ -59,7 +59,7 @@ OPTIONS
Useful for patch series and the like.
-u::
Update affected files from cvs repository before attempting export.
Update affected files from CVS repository before attempting export.
-v::
Verbose.

View File

@@ -102,7 +102,7 @@ No special setup is needed for SSH access, other than having GIT tools
in the PATH. If you have clients that do not accept the CVS_SERVER
environment variable, you can rename git-cvsserver to cvs.
Note: Newer cvs versions (>= 1.12.11) also support specifying
Note: Newer CVS versions (>= 1.12.11) also support specifying
CVS_SERVER directly in CVSROOT like
------

View File

@@ -22,10 +22,10 @@ tree and the index file, or the index file and the working tree.
words, the differences are what you _could_ tell git to
further add to the index but you still haven't. You can
stage these changes by using gitlink:git-add[1].
If exactly two paths are given, and at least one is untracked,
compare the two files / directories. This behavior can be
forced by --no-index.
+
If exactly two paths are given, and at least one is untracked,
compare the two files / directories. This behavior can be
forced by --no-index.
'git-diff' [--options] --cached [<commit>] [--] [<path>...]::
@@ -44,16 +44,34 @@ tree and the index file, or the index file and the working tree.
'git-diff' [--options] <commit> <commit> [--] [<path>...]::
This form is to view the changes between two <commit>,
for example, tips of two branches.
This is to view the changes between two arbitrary
<commit>.
'git-diff' [--options] <commit>..<commit> [--] [<path>...]::
This is synonymous to the previous form. If <commit> on
one side is omitted, it will have the same effect as
using HEAD instead.
'git-diff' [--options] <commit>\...<commit> [--] [<path>...]::
This form is to view the changes on the branch containing
and up to the second <commit>, starting at a common ancestor
of both <commit>. "git-diff A\...B" is equivalent to
"git-diff $(git-merge-base A B) B". You can omit any one
of <commit>, which has the same effect as using HEAD instead.
Just in case if you are doing something exotic, it should be
noted that all of the <commit> in the above description can be
any <tree-ish>.
noted that all of the <commit> in the above description, except
for the last two forms that use ".." notations, can be any
<tree-ish>.
For a more complete list of ways to spell <commit>, see
"SPECIFYING REVISIONS" section in gitlink:git-rev-parse[1].
However, "diff" is about comparing two _endpoints_, not ranges,
and the range notations ("<commit>..<commit>" and
"<commit>\...<commit>") do not mean a range as defined in the
"SPECIFYING RANGES" section in gitlink:git-rev-parse[1].
OPTIONS
-------
@@ -97,6 +115,18 @@ the tip of the current branch, but limit the comparison to the
file "test".
<3> Compare the version before the last commit and the last commit.
Comparing branches::
+
------------
$ git diff topic master <1>
$ git diff topic..master <2>
$ git diff topic...master <3>
------------
+
<1> Changes between the tips of the topic and the master branches.
<2> Same as above.
<3> Changes that occured on the master branch since when the topic
branch was started off it.
Limiting the diff output::
+

View File

@@ -176,6 +176,15 @@ results, such as branch names or file names with leading or trailing
spaces in their name, or early termination of fast-import when it encounters
unexpected input.
Stream Comments
~~~~~~~~~~~~~~~
To aid in debugging frontends fast-import ignores any line that
begins with `#` (ASCII pound/hash) up to and including the line
ending `LF`. A comment line may contain any sequence of bytes
that does not contain an LF and therefore may be used to include
any detailed debugging information that might be specific to the
frontend and useful when inspecting a fast-import data stream.
Date Formats
~~~~~~~~~~~~
The following date formats are supported. A frontend should select
@@ -232,7 +241,7 @@ been well tested in the wild.
+
Frontends should prefer the `raw` format if the source material
already uses UNIX-epoch format, can be coaxed to give dates in that
format, or its format is easiliy convertible to it, as there is no
format, or its format is easily convertible to it, as there is no
ambiguity in parsing.
`now`::
@@ -289,6 +298,11 @@ and control the current import process. More detailed discussion
This command is optional and is not needed to perform
an import.
`progress`::
Causes fast-import to echo the entire line to its own
standard output. This command is optional and is not needed
to perform an import.
`commit`
~~~~~~~~
Create or update a branch with a new commit, recording one logical
@@ -303,7 +317,7 @@ change to the project.
('from' SP <committish> LF)?
('merge' SP <committish> LF)?
(filemodify | filedelete | filecopy | filerename | filedeleteall)*
LF
LF?
....
where `<ref>` is the name of the branch to make the commit on.
@@ -329,11 +343,13 @@ Zero or more `filemodify`, `filedelete`, `filecopy`, `filerename`
and `filedeleteall` commands
may be included to update the contents of the branch prior to
creating the commit. These commands may be supplied in any order.
However it is recommended that a `filedeleteall` command preceed
However it is recommended that a `filedeleteall` command precede
all `filemodify`, `filecopy` and `filerename` commands in the same
commit, as `filedeleteall`
wipes the branch clean (see below).
The `LF` after the command is optional (it used to be required).
`author`
^^^^^^^^
An `author` command may optionally appear, if the author information
@@ -386,7 +402,7 @@ Here `<committish>` is any of the following:
+
The reason fast-import uses `:` to denote a mark reference is this character
is not legal in a Git branch name. The leading `:` makes it easy
to distingush between the mark 42 (`:42`) and the branch 42 (`42`
to distinguish between the mark 42 (`:42`) and the branch 42 (`42`
or `refs/heads/42`), or an abbreviated SHA-1 which happened to
consist only of base-10 digits.
+
@@ -471,7 +487,7 @@ start with double quote (`"`).
If an `LF` or double quote must be encoded into `<path>` shell-style
quoting should be used, e.g. `"path/with\n and \" in it"`.
The value of `<path>` must be in canoncial form. That is it must not:
The value of `<path>` must be in canonical form. That is it must not:
* contain an empty directory component (e.g. `foo//bar` is invalid),
* end with a directory separator (e.g. `foo/` is invalid),
@@ -645,12 +661,14 @@ branch from an existing commit without creating a new commit.
....
'reset' SP <ref> LF
('from' SP <committish> LF)?
LF
LF?
....
For a detailed description of `<ref>` and `<committish>` see above
under `commit` and `from`.
The `LF` after the command is optional (it used to be required).
The `reset` command can also be used to create lightweight
(non-annotated) tags. For example:
@@ -689,29 +707,40 @@ intended for production-quality conversions should always use the
exact byte count format, as it is more robust and performs better.
The delimited format is intended primarily for testing fast-import.
Comment lines appearing within the `<raw>` part of `data` commands
are always taken to be part of the body of the data and are therefore
never ignored by fast-import. This makes it safe to import any
file/message content whose lines might start with `#`.
Exact byte count format::
The frontend must specify the number of bytes of data.
+
....
'data' SP <count> LF
<raw> LF
<raw> LF?
....
+
where `<count>` is the exact number of bytes appearing within
`<raw>`. The value of `<count>` is expressed as an ASCII decimal
integer. The `LF` on either side of `<raw>` is not
included in `<count>` and will not be included in the imported data.
+
The `LF` after `<raw>` is optional (it used to be required) but
recommended. Always including it makes debugging a fast-import
stream easier as the next command always starts in column 0
of the next line, even if `<raw>` did not end with an `LF`.
Delimited format::
A delimiter string is used to mark the end of the data.
fast-import will compute the length by searching for the delimiter.
This format is primarly useful for testing and is not
This format is primarily useful for testing and is not
recommended for real data.
+
....
'data' SP '<<' <delim> LF
<raw> LF
<delim> LF
LF?
....
+
where `<delim>` is the chosen delimiter string. The string `<delim>`
@@ -720,6 +749,8 @@ fast-import will think the data ends earlier than it really does. The `LF`
immediately trailing `<raw>` is part of `<raw>`. This is one of
the limitations of the delimited format, it is impossible to supply
a data chunk which does not have an LF as its last byte.
+
The `LF` after `<delim> LF` is optional (it used to be required).
`checkpoint`
~~~~~~~~~~~~
@@ -728,7 +759,7 @@ save out all current branch refs, tags and marks.
....
'checkpoint' LF
LF
LF?
....
Note that fast-import automatically switches packfiles when the current
@@ -747,6 +778,32 @@ process access to a branch. However given that a 30 GiB Subversion
repository can be loaded into Git through fast-import in about 3 hours,
explicit checkpointing may not be necessary.
The `LF` after the command is optional (it used to be required).
`progress`
~~~~~~~~~~
Causes fast-import to print the entire `progress` line unmodified to
its standard output channel (file descriptor 1) when the command is
processed from the input stream. The command otherwise has no impact
on the current import, or on any of fast-import's internal state.
....
'progress' SP <any> LF
LF?
....
The `<any>` part of the command may contain any sequence of bytes
that does not contain `LF`. The `LF` after the command is optional.
Callers may wish to process the output through a tool such as sed to
remove the leading part of the line, for example:
====
frontend | git-fast-import | sed 's/^progress //'
====
Placing a `progress` command immediately after a `checkpoint` will
inform the reader when the `checkpoint` has been completed and it
can safely access the refs that fast-import updated.
Tips and Tricks
---------------
@@ -816,7 +873,7 @@ to remove the dummy branch.
Import Now, Repack Later
~~~~~~~~~~~~~~~~~~~~~~~~
As soon as fast-import completes the Git repository is completely valid
and ready for use. Typicallly this takes only a very short time,
and ready for use. Typically this takes only a very short time,
even for considerably large projects (100,000+ commits).
However repacking the repository is necessary to improve data
@@ -840,6 +897,15 @@ This will take longer, but will also produce a smaller packfile.
You only need to expend the effort once, and everyone using your
project will benefit from the smaller repository.
Include Some Progress Messages
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Every once in a while have your frontend emit a `progress` message
to fast-import. The contents of the messages are entirely free-form,
so one suggestion would be to output the current month and year
each time the current commit date moves into the next month.
Your users will feel better knowing how much of the data stream
has been processed.
Packfile Optimization
---------------------
@@ -876,8 +942,8 @@ Memory Utilization
------------------
There are a number of factors which affect how much memory fast-import
requires to perform an import. Like critical sections of core
Git, fast-import uses its own memory allocators to ammortize any overheads
associated with malloc. In practice fast-import tends to ammoritize any
Git, fast-import uses its own memory allocators to amortize any overheads
associated with malloc. In practice fast-import tends to amortize any
malloc overheads to 0, due to its use of large block allocations.
per object
@@ -934,7 +1000,7 @@ per active tree
~~~~~~~~~~~~~~~
Trees (aka directories) use just 12 bytes of memory on top of the
memory required for their entries (see ``per active file'' below).
The cost of a tree is virtually 0, as its overhead ammortizes out
The cost of a tree is virtually 0, as its overhead amortizes out
over the individual file entries.
per active file entry

View File

@@ -120,7 +120,7 @@ have all of them as parents.
tag name is expected on standard output.
+
The original tags are not deleted, but can be overwritten;
use "--tag-name-filter=cat" to simply update the tags. In this
use "--tag-name-filter cat" to simply update the tags. In this
case, be very careful and make sure you have the old tags
backed up in case the conversion has run afoul.
+

View File

@@ -10,7 +10,7 @@ SYNOPSIS
--------
[verse]
git-fmt-merge-msg [--summary | --no-summary] <$GIT_DIR/FETCH_HEAD
git-fmt-merge-msg [--summary | --no-summray] -F <file>
git-fmt-merge-msg [--summary | --no-summary] -F <file>
DESCRIPTION
-----------

View File

@@ -16,21 +16,35 @@ SYNOPSIS
[--in-reply-to=Message-Id] [--suffix=.<sfx>]
[--ignore-if-in-upstream]
[--subject-prefix=Subject-Prefix]
<since>[..<until>]
[ <since> | <revision range> ]
DESCRIPTION
-----------
Prepare each commit between <since> and <until> with its patch in
Prepare each commit with its patch in
one file per commit, formatted to resemble UNIX mailbox format.
If ..<until> is not specified, the head of the current working
tree is implied. For a more complete list of ways to spell
<since> and <until>, see "SPECIFYING REVISIONS" section in
gitlink:git-rev-parse[1].
The output of this command is convenient for e-mail submission or
for use with gitlink:git-am[1].
There are two ways to specify which commits to operate on.
1. A single commit, <since>, specifies that the commits leading
to the tip of the current branch that are not in the history
that leads to the <since> to be output.
2. Generic <revision range> expression (see "SPECIFYING
REVISIONS" section in gitlink:git-rev-parse[1]) means the
commits in the specified range.
A single commit, when interpreted as a <revision range>
expression, means "everything that leads to that commit", but
if you write 'git format-patch <commit>', the previous rule
applies to that command line and you do not get "everything
since the beginning of the time". If you want to format
everything since project inception to one commit, say "git
format-patch \--root <commit>" to make it clear that it is the
latter case.
By default, each output file is numbered sequentially from 1, and uses the
first line of the commit message (massaged for pathname safety) as
the filename. With the --numbered-files option, the output file names
@@ -118,7 +132,7 @@ include::diff-options.txt[]
--suffix=.<sfx>::
Instead of using `.patch` as the suffix for generated
filenames, use specifed suffix. A common alternative is
filenames, use specified suffix. A common alternative is
`--suffix=.txt`.
+
Note that you would need to include the leading dot `.` if you
@@ -153,6 +167,10 @@ git-format-patch origin::
not in the origin branch. For each commit a separate file
is created in the current directory.
git-format-patch \--root origin::
Extract all commits which that leads to 'origin' since the
inception of the project.
git-format-patch -M -B origin::
The same as the previous one. Additionally, it detects
and handles renames and complete rewrites intelligently to

View File

@@ -89,7 +89,7 @@ See Also
Other
-----
git-gui is actually maintained as an independent project, but stable
versions are distributed as part of the Git suite for the convience
versions are distributed as part of the Git suite for the convenience
of end users.
A git-gui development repository can be obtained from:

View File

@@ -34,7 +34,7 @@ commit-id::
the local end after the transfer is complete.
--stdin::
Instead of a commit id on the commandline (which is not expected in this
Instead of a commit id on the command line (which is not expected in this
case), 'git-http-fetch' expects lines on stdin in the format
<commit-id>['\t'<filename-as-in--w>]

View File

@@ -44,7 +44,7 @@ OPTIONS
the local end after the transfer is complete.
--stdin::
Instead of a commit id on the commandline (which is not expected in this
Instead of a commit id on the command line (which is not expected in this
case), 'git-local-fetch' expects lines on stdin in the format
<commit-id>['\t'<filename-as-in--w>]

View File

@@ -49,6 +49,7 @@ include::pretty-options.txt[]
-g, \--walk-reflogs::
Show commits as they were recorded in the reflog. The log contains
a record about how the tip of a reference was changed.
Cannot be combined with --reverse.
See also gitlink:git-reflog[1].
--decorate::
@@ -95,7 +96,7 @@ git log --since="2 weeks ago" \-- gitk::
The "--" is necessary to avoid confusion with the *branch* named
'gitk'
git log -r --name-status release..test::
git log --name-status release..test::
Show the commits that are in the "test" branch but not yet
in the "release" branch, along with the list of paths

View File

@@ -37,7 +37,7 @@ OPTIONS
--name-only::
Instead of printing both the SHA-1 and the name, print only
the name. If given with --tags the usual tag prefix of
"tags/" is also ommitted from the name, matching the output
"tags/" is also omitted from the name, matching the output
of gitlink::git-describe[1] more closely. This option
cannot be combined with --stdin.

View File

@@ -78,7 +78,7 @@ The hook should exit with non-zero status if it wants to disallow
updating the named ref. Otherwise it should exit with zero.
Successful execution (a zero exit status) of this hook does not
ensure the ref will actully be updated, it is only a prerequisite.
ensure the ref will actually be updated, it is only a prerequisite.
As such it is not a good idea to send notices (e.g. email) from
this hook. Consider using the post-receive hook instead.

View File

@@ -30,9 +30,10 @@ Entries older than `expire` time, or entries older than
tip, are removed from the reflog. This is typically not used
directly by the end users -- instead, see gitlink:git-gc[1].
The subcommand "show" (which is also the default, in the absense of any
The subcommand "show" (which is also the default, in the absence of any
subcommands) will take all the normal log options, and show the log of
the current branch. It is basically an alias for 'git log -g --abbrev-commit
`HEAD`, which will cover all recent actions, including branch switches.
It is basically an alias for 'git log -g --abbrev-commit
--pretty=oneline', see gitlink:git-log[1].

View File

@@ -14,7 +14,7 @@ DESCRIPTION
-----------
This script is used to combine all objects that do not currently
reside in a "pack", into a pack. It can also be used to re-organise
reside in a "pack", into a pack. It can also be used to re-organize
existing packs into a single, more efficient pack.
A pack is a collection of objects, individually compressed, with

View File

@@ -113,7 +113,7 @@ e.g. "2 hours ago".
`--date=rfc` (or `--date=rfc2822`) shows timestamps in RFC 2822
format, often found in E-mail messages.
+
`--date=short` shows only date but not time, in `YYYY-MM-DD` fomat.
`--date=short` shows only date but not time, in `YYYY-MM-DD` format.
+
`--date=default` shows timestamps in the original timezone
(either committer's or author's).
@@ -299,6 +299,8 @@ used in the output. When the starting commit is specified as
instead. Under '\--pretty=oneline', the commit message is
prefixed with this information on the same line.
Cannot be combined with '\--reverse'.
--merge::
After a failed merge, show refs that touch files having a
@@ -373,6 +375,7 @@ By default, the commits are shown in reverse chronological order.
--reverse::
Output the commits in reverse order.
Cannot be combined with '\--walk-reflogs'.
Object Traversal
~~~~~~~~~~~~~~~~

View File

@@ -215,7 +215,10 @@ blobs contained in a commit.
* A colon, optionally followed by a stage number (0 to 3) and a
colon, followed by a path; this names a blob object in the
index at the given path. Missing stage number (and the colon
that follows it) names an stage 0 entry.
that follows it) names an stage 0 entry. During a merge, stage
1 is the common ancestor, stage 2 is the target branch's version
(typically the current branch), and stage 3 is the version from
the branch being merged.
Here is an illustration, by Jon Loeliger. Both node B and C are
a commit parents of commit node A. Parent commits are ordered

View File

@@ -62,7 +62,7 @@ The --cc option must be repeated for each user you want on the cc list.
--signed-off-by-cc, --no-signed-off-by-cc::
If this is set, add emails found in Signed-off-by: or Cc: lines to the
cc list.
Default is the value of 'sendemail.signedoffbycc' configuration value;
Default is the value of 'sendemail.signedoffcc' configuration value;
if that is unspecified, default to --signed-off-by-cc.
--quiet::
@@ -88,7 +88,7 @@ The --cc option must be repeated for each user you want on the cc list.
If this is set, do not add the From: address to the cc: list, if it
shows up in a From: line.
Default is the value of 'sendemail.suppressfrom' configuration value;
if that is unspecified, default to --no-supress-from.
if that is unspecified, default to --no-suppress-from.
--thread, --no-thread::
If this is set, the In-Reply-To header will be set on each email sent.

View File

@@ -44,10 +44,15 @@ COMMANDS
--tags=<tags_subdir>;;
-b<branches_subdir>;;
--branches=<branches_subdir>;;
-s;;
--stdlayout;;
These are optional command-line options for init. Each of
these flags can point to a relative repository path
(--tags=project/tags') or a full url
(--tags=https://foo.org/project/tags)
(--tags=https://foo.org/project/tags). The option --stdlayout is
a shorthand way of setting trunk,tags,branches as the relative paths,
which is the Subversion default. If any of the other options are given
as well, they take precedence.
--no-metadata;;
Set the 'noMetadata' option in the [svn-remote] config.
--use-svm-props;;
@@ -94,7 +99,7 @@ COMMANDS
This works similarly to 'svn update' or 'git-pull' except that
it preserves linear history with 'git-rebase' instead of
'git-merge' for ease of dcommit-ing with git-svn.
'git-merge' for ease of dcommiting with git-svn.
This accepts all options that 'git-svn fetch' and 'git-rebase'
accepts. However '--fetch-all' only fetches from the current
@@ -479,6 +484,38 @@ the user on the git side. git-svn does however follow copy
history of the directory that it is tracking, however (much like
how 'svn log' works).
CAVEATS
-------
For the sake of simplicity and interoperating with a less-capable system
(SVN), it is recommended that all git-svn users clone, fetch and dcommit
directly from the SVN server, and avoid all git-clone/pull/merge/push
operations between git repositories and branches. The recommended
method of exchanging code between git branches and users is
git-format-patch and git-am, or just dcommiting to the SVN repository.
Running 'git-merge' or 'git-pull' is NOT recommended on a branch you
plan to dcommit from. Subversion does not represent merges in any
reasonable or useful fashion; so users using Subversion cannot see any
merges you've made. Furthermore, if you merge or pull from a git branch
that is a mirror of an SVN branch, dcommit may commit to the wrong
branch.
'git-clone' does not clone branches under the refs/remotes/ hierarchy or
any git-svn metadata, or config. So repositories created and managed with
using git-svn should use rsync(1) for cloning, if cloning is to be done
at all.
Since 'dcommit' uses rebase internally, any git branches you git-push to
before dcommit on will require forcing an overwrite of the existing ref
on the remote repository. This is generally considered bad practice,
see the git-push(1) documentation for details.
Do not use the --amend option of git-commit(1) on a change you've
already dcommitted. It is considered bad practice to --amend commits
you've already pushed to a remote repository for other users, and
dcommit with SVN is analogous to that.
BUGS
----
@@ -512,9 +549,9 @@ listed below are allowed:
------------------------------------------------------------------------
Keep in mind that the '*' (asterisk) wildcard of the local ref
(left of the ':') *must* be the farthest right path component;
(right of the ':') *must* be the farthest right path component;
however the remote wildcard may be anywhere as long as it's own
independent path componet (surrounded by '/' or EOL). This
independent path component (surrounded by '/' or EOL). This
type of configuration is not automatically created by 'init' and
should be manually entered with a text-editor or using
gitlink:git-config[1]

View File

@@ -68,6 +68,9 @@ When importing incrementally, you might need to edit the .git/svn2git file.
Prepend 'rX: ' to commit messages, where X is the imported
subversion revision.
-u::
Replace underscores in tag names with periods.
-I <ignorefile_name>::
Import the svn:ignore directory property to files with this
name in each directory. (The Subversion and GIT ignore

View File

@@ -34,13 +34,6 @@ 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.
`-v <tag>` verifies the gpg signature of the tag.
`-l <pattern>` lists tags with names that match the given pattern
(or all if no pattern is given).
OPTIONS
-------
-a::

View File

@@ -42,16 +42,13 @@ OPTIONS
CONFIGURATION
-------------
By default, file and directories modes are set to 0666 or 0777. It is
possible to change this by setting the "umask" variable in the
repository configuration as follows :
[tar]
umask = 002 ;# group friendly
The special umask value "user" indicates that the user's current umask
will be used instead. The default value is 002, which means group
readable/writable files and directories.
tar.umask::
This variable can be used to restrict the permission bits of
tar archive entries. The default is 0002, which turns off the
world write bit. The special value "user" indicates that the
archiving user's umask will be used instead. See umask(2) for
details.
EXAMPLES
--------

View File

@@ -9,7 +9,8 @@ git - the stupid content tracker
SYNOPSIS
--------
[verse]
'git' [--version] [--exec-path[=GIT_EXEC_PATH]] [-p|--paginate]
'git' [--version] [--exec-path[=GIT_EXEC_PATH]]
[-p|--paginate|--no-pager]
[--bare] [--git-dir=GIT_DIR] [--work-tree=GIT_WORK_TREE]
[--help] COMMAND [ARGS]
@@ -103,6 +104,9 @@ OPTIONS
-p|--paginate::
Pipe all output into 'less' (or if set, $PAGER).
--no-pager::
Do not pipe git output into a pager.
--git-dir=<path>::
Set the path to the repository. This can also be controlled by
setting the GIT_DIR environment variable.
@@ -116,7 +120,10 @@ OPTIONS
variable.
--bare::
Same as --git-dir=`pwd`.
Treat the repository as a bare repository. If GIT_DIR
environment is not set, it is set to the current working
directory.
FURTHER DOCUMENTATION
---------------------

View File

@@ -285,7 +285,7 @@ want to appear as the hunk header, like this:
Note. A single level of backslashes are eaten by the
configuration file parser, so you would need to double the
backslashes; the pattern above picks a line that begins with a
backslash, and zero or more occurences of `sub` followed by
backslash, and zero or more occurrences of `sub` followed by
`section` followed by open brace, to the end of line.
There are a few built-in patterns to make this easier, and `tex`
@@ -394,7 +394,7 @@ abc -foo -bar
the attributes given to path `t/abc` are computed as follows:
1. By examining `t/.gitattributes` (which is in the same
diretory as the path in question), git finds that the first
directory as the path in question), git finds that the first
line matches. `merge` attribute is set. It also finds that
the second line matches, and attributes `foo` and `bar`
are unset.
@@ -410,7 +410,7 @@ the attributes given to path `t/abc` are computed as follows:
a match, and `foo` is set, `bar` is reverted to unspecified
state, and `baz` is unset.
As the result, the attributes assignement to `t/abc` becomes:
As the result, the attributes assignment to `t/abc` becomes:
----------------------------------------------------------------
foo set to true

View File

@@ -176,7 +176,7 @@ hook does on its standard input.
This hook does not affect the outcome of `git-receive-pack`, as it
is called after the real work is done.
This supersedes the <<post-update,'post-update'>> hook in that it get's
This supersedes the <<post-update,'post-update'>> hook in that it gets
both old and new values of all the refs in addition to their
names.

View File

@@ -339,7 +339,7 @@ $ git pull . remotes/bob/master
-------------------------------------
Note that git pull always merges into the current branch,
regardless of what else is given on the commandline.
regardless of what else is given on the command line.
Later, Bob can update his repo with Alice's latest changes using

View File

@@ -4,7 +4,7 @@ ______________________________________________
Git is a fast distributed revision control system.
This manual is designed to be readable by someone with basic unix
This manual is designed to be readable by someone with basic UNIX
command-line skills, but no previous knowledge of git.
<<repositories-and-branches>> and <<exploring-git-history>> explain how
@@ -42,10 +42,9 @@ How to get a git repository
It will be useful to have a git repository to experiment with as you
read this manual.
The best way to get one is by using the gitlink:git-clone[1] command
to download a copy of an existing repository for a project that you
are interested in. If you don't already have a project in mind, here
are some interesting examples:
The best way to get one is by using the gitlink:git-clone[1] command to
download a copy of an existing repository. If you don't already have a
project in mind, here are some interesting examples:
------------------------------------------------
# git itself (approx. 10MB download):
@@ -63,21 +62,18 @@ directory, you will see that it contains a copy of the project files,
together with a special top-level directory named ".git", which
contains all the information about the history of the project.
In most of the following, examples will be taken from one of the two
repositories above.
[[how-to-check-out]]
How to check out a different version of a project
-------------------------------------------------
Git is best thought of as a tool for storing the history of a
collection of files. It stores the history as a compressed
collection of interrelated snapshots (versions) of the project's
contents.
Git is best thought of as a tool for storing the history of a collection
of files. It stores the history as a compressed collection of
interrelated snapshots of the project's contents. In git each such
version is called a <<def_commit,commit>>.
A single git repository may contain multiple branches. It keeps track
of them by keeping a list of <<def_head,heads>> which reference the
latest version on each branch; the gitlink:git-branch[1] command shows
latest commit on each branch; the gitlink:git-branch[1] command shows
you the list of branch heads:
------------------------------------------------
@@ -149,32 +145,27 @@ current branch:
------------------------------------------------
$ git show
commit 2b5f6dcce5bf94b9b119e9ed8d537098ec61c3d2
Author: Jamal Hadi Salim <hadi@cyberus.ca>
Date: Sat Dec 2 22:22:25 2006 -0800
commit 17cf781661e6d38f737f15f53ab552f1e95960d7
Author: Linus Torvalds <torvalds@ppc970.osdl.org.(none)>
Date: Tue Apr 19 14:11:06 2005 -0700
[XFRM]: Fix aevent structuring to be more complete.
Remove duplicate getenv(DB_ENVIRONMENT) call
aevents can not uniquely identify an SA. We break the ABI with this
patch, but consensus is that since it is not yet utilized by any
(known) application then it is fine (better do it now than later).
Noted by Tony Luck.
Signed-off-by: Jamal Hadi Salim <hadi@cyberus.ca>
Signed-off-by: David S. Miller <davem@davemloft.net>
diff --git a/Documentation/networking/xfrm_sync.txt b/Documentation/networking/xfrm_sync.txt
index 8be626f..d7aac9d 100644
--- a/Documentation/networking/xfrm_sync.txt
+++ b/Documentation/networking/xfrm_sync.txt
@@ -47,10 +47,13 @@ aevent_id structure looks like:
struct xfrm_aevent_id {
struct xfrm_usersa_id sa_id;
+ xfrm_address_t saddr;
__u32 flags;
+ __u32 reqid;
};
...
diff --git a/init-db.c b/init-db.c
index 65898fa..b002dc6 100644
--- a/init-db.c
+++ b/init-db.c
@@ -7,7 +7,7 @@
int main(int argc, char **argv)
{
- char *sha1_dir = getenv(DB_ENVIRONMENT), *path;
+ char *sha1_dir, *path;
int len, i;
if (mkdir(".git", 0755) < 0) {
------------------------------------------------
As you can see, a commit shows who made the latest change, what they
@@ -217,7 +208,7 @@ commits will help understand how the git organizes history.
In the following, we say that commit X is "reachable" from commit Y
if commit X is an ancestor of commit Y. Equivalently, you could say
that Y is a descendent of X, or that there is a chain of parents
that Y is a descendant of X, or that there is a chain of parents
leading from commit Y to commit X.
[[history-diagrams]]
@@ -923,14 +914,14 @@ they look OK.
[[Finding-comments-with-given-content]]
Finding commits referencing a file with given content
-----------------------------------------------------
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Somebody hands you a copy of a file, and asks which commits modified a
file such that it contained the given content either before or after the
commit. You can find out with this:
-------------------------------------------------
$ git log --raw -r --abbrev=40 --pretty=oneline -- filename |
$ git log --raw --abbrev=40 --pretty=oneline -- filename |
grep -B 1 `git hash-object filename`
-------------------------------------------------
@@ -1105,20 +1096,14 @@ backup files made by your editor. Of course, 'not' tracking files with git
is just a matter of 'not' calling "`git add`" on them. But it quickly becomes
annoying to have these untracked files lying around; e.g. they make
"`git add .`" and "`git commit -a`" practically useless, and they keep
showing up in the output of "`git status`", etc.
showing up in the output of "`git status`".
Git therefore provides "exclude patterns" for telling git which files to
actively ignore. Exclude patterns are thoroughly explained in the
gitlink:gitignore[5] manual page, but the heart of the concept is simply
a list of files which git should ignore. Entries in the list may contain
globs to specify multiple files, or may be prefixed by "`!`" to
explicitly include (un-ignore) a previously excluded (ignored) file
(i.e. later exclude patterns override earlier ones). The following
example should illustrate such patterns:
You can tell git to ignore certain files by creating a file called .gitignore
in the top level of your working directory, with contents such as:
-------------------------------------------------
# Lines starting with '#' are considered comments.
# Ignore foo.txt.
# Ignore any file named foo.txt.
foo.txt
# Ignore (generated) html files,
*.html
@@ -1128,41 +1113,20 @@ foo.txt
*.[oa]
-------------------------------------------------
The next question is where to put these exclude patterns so that git can
find them. Git looks for exclude patterns in the following files:
See gitlink:gitignore[5] for a detailed explanation of the syntax. You can
also place .gitignore files in other directories in your working tree, and they
will apply to those directories and their subdirectories. The `.gitignore`
files can be added to your repository like any other files (just run `git add
.gitignore` and `git commit`, as usual), which is convenient when the exclude
patterns (such as patterns matching build output files) would also make sense
for other users who clone your repository.
`.gitignore` files in your working tree:::
You may store multiple `.gitignore` files at various locations in your
working tree. Each `.gitignore` file is applied to the directory where
it's located, including its subdirectories. Furthermore, the
`.gitignore` files can be tracked like any other files in your working
tree; just do a "`git add .gitignore`" and commit. `.gitignore` is
therefore the right place to put exclude patterns that are meant to
be shared between all project participants, such as build output files
(e.g. `\*.o`), etc.
`.git/info/exclude` in your repo:::
Exclude patterns in this file are applied to the working tree as a
whole. Since the file is not located in your working tree, it does
not follow push/pull/clone like `.gitignore` can do. This is therefore
the place to put exclude patterns that are local to your copy of the
repo (i.e. 'not' shared between project participants), such as
temporary backup files made by your editor (e.g. `\*~`), etc.
The file specified by the `core.excludesfile` config directive:::
By setting the `core.excludesfile` config directive you can tell git
where to find more exclude patterns (see gitlink:git-config[1] for
more information on configuration options). This config directive
can be set in the per-repo `.git/config` file, in which case the
exclude patterns will apply to that repo only. Alternatively, you
can set the directive in the global `~/.gitconfig` file to apply
the exclude pattern to all your git repos. As with the above
`.git/info/exclude` (and, indeed, with git config directives in
general), this directive does not follow push/pull/clone, but remain
local to your repo(s).
[NOTE]
In addition to the above alternatives, there are git commands that can take
exclude patterns directly on the command line. See gitlink:git-ls-files[1]
for an example of this.
If you wish the exclude patterns to affect only certain repositories
(instead of every repository for a given project), you may instead put
them in a file in your repository named .git/info/exclude, or in any file
specified by the `core.excludesfile` configuration variable. Some git
commands can also take exclude patterns directly on the command line.
See gitlink:gitignore[5] for the details.
[[how-to-merge]]
How to merge
@@ -1796,11 +1760,12 @@ taken from the message containing each patch.
Public git repositories
-----------------------
Another way to submit changes to a project is to tell the maintainer of
that project to pull the changes from your repository using git-pull[1].
In the section "<<getting-updates-with-git-pull, Getting updates with
git pull>>" we described this as a way to get updates from the "main"
repository, but it works just as well in the other direction.
Another way to submit changes to a project is to tell the maintainer
of that project to pull the changes from your repository using
gitlink:git-pull[1]. In the section "<<getting-updates-with-git-pull,
Getting updates with git pull>>" we described this as a way to get
updates from the "main" repository, but it works just as well in the
other direction.
If you and the maintainer both have accounts on the same machine, then
you can just pull changes from each other's repositories directly;
@@ -1911,7 +1876,7 @@ gitlink:git-update-server-info[1], and the documentation
link:hooks.html[Hooks used by git].)
Advertise the url of proj.git. Anybody else should then be able to
clone or pull from that url, for example with a commandline like:
clone or pull from that url, for example with a command line like:
-------------------------------------------------
$ git clone http://yourserver.com/~you/proj.git
@@ -2057,7 +2022,8 @@ $ cd work
Linus's tree will be stored in the remote branch named origin/master,
and can be updated using gitlink:git-fetch[1]; you can track other
public trees using gitlink:git-remote[1] to set up a "remote" and
git-fetch[1] to keep them up-to-date; see <<repositories-and-branches>>.
gitlink:git-fetch[1] to keep them up-to-date; see
<<repositories-and-branches>>.
Now create the branches in which you are going to work; these start out
at the current tip of origin/master branch, and should be set up (using
@@ -2512,9 +2478,9 @@ $ gitk origin..mywork &
And browse through the list of patches in the mywork branch using gitk,
applying them (possibly in a different order) to mywork-new using
cherry-pick, and possibly modifying them as you go using commit --amend.
The git-gui[1] command may also help as it allows you to individually
select diff hunks for inclusion in the index (by right-clicking on the
diff hunk and choosing "Stage Hunk for Commit").
The gitlink:git-gui[1] command may also help as it allows you to
individually select diff hunks for inclusion in the index (by
right-clicking on the diff hunk and choosing "Stage Hunk for Commit").
Another technique is to use git-format-patch to create a series of
patches, then reset the state to before the patches:
@@ -2531,7 +2497,7 @@ them again with gitlink:git-am[1].
Other tools
-----------
There are numerous other tools, such as stgit, which exist for the
There are numerous other tools, such as StGIT, which exist for the
purpose of maintaining a patch series. These are outside of the scope of
this manual.
@@ -3961,8 +3927,8 @@ This is a work in progress.
The basic requirements:
- It must be readable in order, from beginning to end, by
someone intelligent with a basic grasp of the unix
commandline, but without any special knowledge of git. If
someone intelligent with a basic grasp of the UNIX
command line, but without any special knowledge of git. If
necessary, any other prerequisites should be specifically
mentioned as they arise.
- Whenever possible, section headings should clearly describe

View File

@@ -14,7 +14,7 @@
#include "revision.h"
static const char builtin_add_usage[] =
"git-add [-n] [-v] [-f] [--interactive | -i] [-u] [--] <filepattern>...";
"git-add [-n] [-v] [-f] [--interactive | -i] [-u] [--refresh] [--] <filepattern>...";
static int take_worktree_changes;
static const char *excludes_file;
@@ -155,7 +155,7 @@ static int git_add_config(const char *var, const char *value)
static struct lock_file lock_file;
static const char ignore_warning[] =
static const char ignore_error[] =
"The following paths are ignored by one of your .gitignore files:\n";
int cmd_add(int argc, const char **argv, const char *prefix)
@@ -250,12 +250,12 @@ int cmd_add(int argc, const char **argv, const char *prefix)
die("index file corrupt");
if (dir.ignored_nr) {
fprintf(stderr, ignore_warning);
fprintf(stderr, ignore_error);
for (i = 0; i < dir.ignored_nr; i++) {
fprintf(stderr, "%s\n", dir.ignored[i]->name);
}
fprintf(stderr, "Use -f if you really want to add them.\n");
exit(1);
die("no files added");
}
for (i = 0; i < dir.nr; i++)

View File

@@ -98,6 +98,10 @@ static char *fill_origin_blob(struct origin *o, mmfile_t *file)
num_read_blob++;
file->ptr = read_sha1_file(o->blob_sha1, &type,
(unsigned long *)(&(file->size)));
if (!file->ptr)
die("Cannot read blob %s for path %s",
sha1_to_hex(o->blob_sha1),
o->path);
o->file = *file;
}
else
@@ -1384,6 +1388,9 @@ static void get_commit_info(struct commit *commit,
unsigned long size;
commit->buffer =
read_sha1_file(commit->object.sha1, &type, &size);
if (!commit->buffer)
die("Cannot read commit %s",
sha1_to_hex(commit->object.sha1));
}
ret->author = author_buf;
get_ac_line(commit->buffer, "\nauthor ",
@@ -2382,6 +2389,10 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
sb.final_buf = read_sha1_file(o->blob_sha1, &type,
&sb.final_buf_size);
if (!sb.final_buf)
die("Cannot read blob %s for path %s",
sha1_to_hex(o->blob_sha1),
path);
}
num_read_blob++;
lno = prepare_lines(&sb);

View File

@@ -277,6 +277,44 @@ static int create_default_files(const char *git_dir, const char *template_path)
return reinit;
}
static void guess_repository_type(const char *git_dir)
{
char cwd[PATH_MAX];
const char *slash;
if (0 <= is_bare_repository_cfg)
return;
if (!git_dir)
return;
/*
* "GIT_DIR=. git init" is always bare.
* "GIT_DIR=`pwd` git init" too.
*/
if (!strcmp(".", git_dir))
goto force_bare;
if (!getcwd(cwd, sizeof(cwd)))
die("cannot tell cwd");
if (!strcmp(git_dir, cwd))
goto force_bare;
/*
* "GIT_DIR=.git or GIT_DIR=something/.git is usually not.
*/
if (!strcmp(git_dir, ".git"))
return;
slash = strrchr(git_dir, '/');
if (slash && !strcmp(slash, "/.git"))
return;
/*
* Otherwise it is often bare. At this point
* we are just guessing.
*/
force_bare:
is_bare_repository_cfg = 1;
return;
}
static const char init_db_usage[] =
"git-init [-q | --quiet] [--template=<template-directory>] [--shared]";
@@ -309,11 +347,28 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
usage(init_db_usage);
}
git_work_tree_cfg = xcalloc(PATH_MAX, 1);
if (!getcwd(git_work_tree_cfg, PATH_MAX))
die ("Cannot access current working directory.");
if (access(get_git_work_tree(), X_OK))
die ("Cannot access work tree '%s'", get_git_work_tree());
/*
* GIT_WORK_TREE makes sense only in conjunction with GIT_DIR
* without --bare. Catch the error early.
*/
git_dir = getenv(GIT_DIR_ENVIRONMENT);
if ((!git_dir || is_bare_repository_cfg == 1)
&& getenv(GIT_WORK_TREE_ENVIRONMENT))
die("%s (or --work-tree=<directory>) not allowed without "
"specifying %s (or --git-dir=<directory>)",
GIT_WORK_TREE_ENVIRONMENT,
GIT_DIR_ENVIRONMENT);
guess_repository_type(git_dir);
if (is_bare_repository_cfg <= 0) {
git_work_tree_cfg = xcalloc(PATH_MAX, 1);
if (!getcwd(git_work_tree_cfg, PATH_MAX))
die ("Cannot access current working directory.");
if (access(get_git_work_tree(), X_OK))
die ("Cannot access work tree '%s'",
get_git_work_tree());
}
/*
* Set up the default .git directory contents

View File

@@ -55,6 +55,7 @@ static void cmd_log_init(int argc, const char **argv, const char *prefix,
rev->abbrev = DEFAULT_ABBREV;
rev->commit_format = CMIT_FMT_DEFAULT;
rev->verbose_header = 1;
rev->diffopt.recursive = 1;
rev->show_root_diff = default_show_root;
rev->subject_prefix = fmt_patch_subject_prefix;
argc = setup_revisions(argc, argv, rev, "HEAD");
@@ -116,7 +117,6 @@ int cmd_whatchanged(int argc, const char **argv, const char *prefix)
git_config(git_log_config);
init_revisions(&rev, prefix);
rev.diff = 1;
rev.diffopt.recursive = 1;
rev.simplify_history = 0;
cmd_log_init(argc, argv, prefix, &rev);
if (!rev.diffopt.output_format)
@@ -165,7 +165,6 @@ int cmd_show(int argc, const char **argv, const char *prefix)
git_config(git_log_config);
init_revisions(&rev, prefix);
rev.diff = 1;
rev.diffopt.recursive = 1;
rev.combine_merges = 1;
rev.dense_combined_merges = 1;
rev.always_show_header = 1;
@@ -586,12 +585,19 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
}
if (rev.pending.nr == 1) {
if (rev.max_count < 0) {
if (rev.max_count < 0 && !rev.show_root_diff) {
/*
* This is traditional behaviour of "git format-patch
* origin" that prepares what the origin side still
* does not have.
*/
rev.pending.objects[0].item->flags |= UNINTERESTING;
add_head(&rev);
}
/* Otherwise, it is "format-patch -22 HEAD", and
* get_revision() would return only the specified count.
/*
* Otherwise, it is "format-patch -22 HEAD", and/or
* "format-patch --root HEAD". The user wants
* get_revision() to do the usual traversal.
*/
}

View File

@@ -11,14 +11,17 @@ static const char name_rev_usage[] =
typedef struct rev_name {
const char *tip_name;
int merge_traversals;
int generation;
int distance;
} rev_name;
static long cutoff = LONG_MAX;
/* How many generations are maximally preferred over _one_ merge traversal? */
#define MERGE_TRAVERSAL_WEIGHT 65535
static void name_rev(struct commit *commit,
const char *tip_name, int merge_traversals, int generation,
const char *tip_name, int generation, int distance,
int deref)
{
struct rev_name *name = (struct rev_name *)commit->util;
@@ -45,13 +48,11 @@ static void name_rev(struct commit *commit,
name = xmalloc(sizeof(rev_name));
commit->util = name;
goto copy_data;
} else if (name->merge_traversals > merge_traversals ||
(name->merge_traversals == merge_traversals &&
name->generation > generation)) {
} else if (name->distance > distance) {
copy_data:
name->tip_name = tip_name;
name->merge_traversals = merge_traversals;
name->generation = generation;
name->distance = distance;
} else
return;
@@ -74,11 +75,11 @@ copy_data:
sprintf(new_name, "%.*s^%d", len, tip_name,
parent_number);
name_rev(parents->item, new_name,
merge_traversals + 1 , 0, 0);
name_rev(parents->item, new_name, 0,
distance + MERGE_TRAVERSAL_WEIGHT, 0);
} else {
name_rev(parents->item, tip_name, merge_traversals,
generation + 1, 0);
name_rev(parents->item, tip_name, generation + 1,
distance + 1, 0);
}
}
}

View File

@@ -979,6 +979,8 @@ static void add_pbase_object(struct tree_desc *tree,
int cmp;
while (tree_entry(tree,&entry)) {
if (S_ISGITLINK(entry.mode))
continue;
cmp = tree_entry_len(entry.path, entry.sha1) != cmplen ? 1 :
memcmp(name, entry.path, cmplen);
if (cmp > 0)
@@ -1354,6 +1356,9 @@ static int try_delta(struct unpacked *trg, struct unpacked *src,
/* Load data if not already done */
if (!trg->data) {
trg->data = read_sha1_file(trg_entry->idx.sha1, &type, &sz);
if (!trg->data)
die("object %s cannot be read",
sha1_to_hex(trg_entry->idx.sha1));
if (sz != trg_size)
die("object %s inconsistent object length (%lu vs %lu)",
sha1_to_hex(trg_entry->idx.sha1), sz, trg_size);
@@ -1361,6 +1366,9 @@ static int try_delta(struct unpacked *trg, struct unpacked *src,
}
if (!src->data) {
src->data = read_sha1_file(src_entry->idx.sha1, &type, &sz);
if (!src->data)
die("object %s cannot be read",
sha1_to_hex(src_entry->idx.sha1));
if (sz != src_size)
die("object %s inconsistent object length (%lu vs %lu)",
sha1_to_hex(src_entry->idx.sha1), sz, src_size);

View File

@@ -72,6 +72,7 @@ int cmd_write_tree(int argc, const char **argv, const char *unused_prefix)
const char *prefix = NULL;
unsigned char sha1[20];
git_config(git_default_config);
while (1 < argc) {
const char *arg = argv[1];
if (!strcmp(arg, "--missing-ok"))

View File

@@ -419,7 +419,7 @@ _git_add ()
local cur="${COMP_WORDS[COMP_CWORD]}"
case "$cur" in
--*)
__gitcomp "--interactive"
__gitcomp "--interactive --refresh"
return
esac
COMPREPLY=()
@@ -459,6 +459,35 @@ _git_branch ()
__gitcomp "$(__git_refs)"
}
_git_bundle ()
{
local mycword="$COMP_CWORD"
case "${COMP_WORDS[0]}" in
git)
local cmd="${COMP_WORDS[2]}"
mycword="$((mycword-1))"
;;
git-bundle*)
local cmd="${COMP_WORDS[1]}"
;;
esac
case "$mycword" in
1)
__gitcomp "create list-heads verify unbundle"
;;
2)
# looking for a file
;;
*)
case "$cmd" in
create)
__git_complete_revlist
;;
esac
;;
esac
}
_git_checkout ()
{
__gitcomp "$(__git_refs)"
@@ -496,6 +525,11 @@ _git_commit ()
COMPREPLY=()
}
_git_describe ()
{
__gitcomp "$(__git_refs)"
}
_git_diff ()
{
__git_complete_file
@@ -544,6 +578,7 @@ _git_format_patch ()
--stdout --attach --thread
--output-directory
--numbered --start-number
--numbered-files
--keep-subject
--signoff
--in-reply-to=
@@ -561,7 +596,7 @@ _git_gc ()
local cur="${COMP_WORDS[COMP_CWORD]}"
case "$cur" in
--*)
__gitcomp "--prune"
__gitcomp "--prune --aggressive"
return
;;
esac
@@ -588,14 +623,20 @@ _git_log ()
" "" "${cur##--pretty=}"
return
;;
--date=*)
__gitcomp "
relative iso8601 rfc2822 short local default
" "" "${cur##--date=}"
return
;;
--*)
__gitcomp "
--max-count= --max-age= --since= --after=
--min-age= --before= --until=
--root --topo-order --date-order --reverse
--no-merges
--no-merges --follow
--abbrev-commit --abbrev=
--relative-date
--relative-date --date=
--author= --committer= --grep=
--all-match
--pretty= --name-status --name-only --raw
@@ -767,7 +808,7 @@ _git_config ()
case "$cur" in
--*)
__gitcomp "
--global --system
--global --system --file=
--list --replace-all
--get --get-all --get-regexp
--add --unset --unset-all
@@ -810,6 +851,7 @@ _git_config ()
core.ignoreStat
core.preferSymlinkRefs
core.logAllRefUpdates
core.loosecompression
core.repositoryFormatVersion
core.sharedRepository
core.warnAmbiguousRefs
@@ -841,6 +883,7 @@ _git_config ()
diff.renames
fetch.unpackLimit
format.headers
format.subjectprefix
gitcvs.enabled
gitcvs.logfile
gitcvs.allbinary
@@ -867,6 +910,10 @@ _git_config ()
merge.verbosity
pack.window
pack.depth
pack.windowMemory
pack.compression
pack.deltaCacheSize
pack.deltaCacheLimit
pull.octopus
pull.twohead
repack.useDeltaBaseOffset
@@ -977,6 +1024,31 @@ _git_stash ()
__gitcomp 'list show apply clear'
}
_git_submodule ()
{
local i c=1 command
while [ $c -lt $COMP_CWORD ]; do
i="${COMP_WORDS[c]}"
case "$i" in
add|status|init|update) command="$i"; break ;;
esac
c=$((++c))
done
if [ $c -eq $COMP_CWORD -a -z "$command" ]; then
local cur="${COMP_WORDS[COMP_CWORD]}"
case "$cur" in
--*)
__gitcomp "--quiet --cached"
;;
*)
__gitcomp "add status init update"
;;
esac
return
fi
}
_git ()
{
local i c=1 command __git_dir
@@ -995,7 +1067,14 @@ _git ()
if [ $c -eq $COMP_CWORD -a -z "$command" ]; then
case "${COMP_WORDS[COMP_CWORD]}" in
--*=*) COMPREPLY=() ;;
--*) __gitcomp "--git-dir= --bare --version --exec-path" ;;
--*) __gitcomp "
--no-pager
--git-dir=
--bare
--version
--exec-path
"
;;
*) __gitcomp "$(__git_commands) $(__git_aliases)" ;;
esac
return
@@ -1009,12 +1088,14 @@ _git ()
add) _git_add ;;
apply) _git_apply ;;
bisect) _git_bisect ;;
bundle) _git_bundle ;;
branch) _git_branch ;;
checkout) _git_checkout ;;
cherry) _git_cherry ;;
cherry-pick) _git_cherry_pick ;;
commit) _git_commit ;;
config) _git_config ;;
describe) _git_describe ;;
diff) _git_diff ;;
fetch) _git_fetch ;;
format-patch) _git_format_patch ;;
@@ -1034,6 +1115,7 @@ _git ()
show) _git_show ;;
show-branch) _git_log ;;
stash) _git_stash ;;
submodule) _git_submodule ;;
whatchanged) _git_log ;;
*) COMPREPLY=() ;;
esac
@@ -1057,10 +1139,12 @@ complete -o default -o nospace -F _git_am git-am
complete -o default -o nospace -F _git_apply git-apply
complete -o default -o nospace -F _git_bisect git-bisect
complete -o default -o nospace -F _git_branch git-branch
complete -o default -o nospace -F _git_bundle git-bundle
complete -o default -o nospace -F _git_checkout git-checkout
complete -o default -o nospace -F _git_cherry git-cherry
complete -o default -o nospace -F _git_cherry_pick git-cherry-pick
complete -o default -o nospace -F _git_commit git-commit
complete -o default -o nospace -F _git_describe git-describe
complete -o default -o nospace -F _git_diff git-diff
complete -o default -o nospace -F _git_fetch git-fetch
complete -o default -o nospace -F _git_format_patch git-format-patch
@@ -1080,6 +1164,7 @@ complete -o default -o nospace -F _git_reset git-reset
complete -o default -o nospace -F _git_shortlog git-shortlog
complete -o default -o nospace -F _git_show git-show
complete -o default -o nospace -F _git_stash git-stash
complete -o default -o nospace -F _git_submodule git-submodule
complete -o default -o nospace -F _git_log git-show-branch
complete -o default -o nospace -F _git_log git-whatchanged
@@ -1092,7 +1177,9 @@ complete -o default -o nospace -F _git_add git-add.exe
complete -o default -o nospace -F _git_apply git-apply.exe
complete -o default -o nospace -F _git git.exe
complete -o default -o nospace -F _git_branch git-branch.exe
complete -o default -o nospace -F _git_bundle git-bundle.exe
complete -o default -o nospace -F _git_cherry git-cherry.exe
complete -o default -o nospace -F _git_describe git-describe.exe
complete -o default -o nospace -F _git_diff git-diff.exe
complete -o default -o nospace -F _git_format_patch git-format-patch.exe
complete -o default -o nospace -F _git_log git-log.exe

View File

@@ -99,47 +99,56 @@ if there is already one that displays the same directory."
(defface git-status-face
'((((class color) (background light)) (:foreground "purple")))
'((((class color) (background light)) (:foreground "purple"))
(((class color) (background dark)) (:foreground "salmon")))
"Git mode face used to highlight added and modified files."
:group 'git)
(defface git-unmerged-face
'((((class color) (background light)) (:foreground "red" :bold t)))
'((((class color) (background light)) (:foreground "red" :bold t))
(((class color) (background dark)) (:foreground "red" :bold t)))
"Git mode face used to highlight unmerged files."
:group 'git)
(defface git-unknown-face
'((((class color) (background light)) (:foreground "goldenrod" :bold t)))
'((((class color) (background light)) (:foreground "goldenrod" :bold t))
(((class color) (background dark)) (:foreground "goldenrod" :bold t)))
"Git mode face used to highlight unknown files."
:group 'git)
(defface git-uptodate-face
'((((class color) (background light)) (:foreground "grey60")))
'((((class color) (background light)) (:foreground "grey60"))
(((class color) (background dark)) (:foreground "grey40")))
"Git mode face used to highlight up-to-date files."
:group 'git)
(defface git-ignored-face
'((((class color) (background light)) (:foreground "grey60")))
'((((class color) (background light)) (:foreground "grey60"))
(((class color) (background dark)) (:foreground "grey40")))
"Git mode face used to highlight ignored files."
:group 'git)
(defface git-mark-face
'((((class color) (background light)) (:foreground "red" :bold t)))
'((((class color) (background light)) (:foreground "red" :bold t))
(((class color) (background dark)) (:foreground "tomato" :bold t)))
"Git mode face used for the file marks."
:group 'git)
(defface git-header-face
'((((class color) (background light)) (:foreground "blue")))
'((((class color) (background light)) (:foreground "blue"))
(((class color) (background dark)) (:foreground "blue")))
"Git mode face used for commit headers."
:group 'git)
(defface git-separator-face
'((((class color) (background light)) (:foreground "brown")))
'((((class color) (background light)) (:foreground "brown"))
(((class color) (background dark)) (:foreground "brown")))
"Git mode face used for commit separator."
:group 'git)
(defface git-permission-face
'((((class color) (background light)) (:foreground "green" :bold t)))
'((((class color) (background light)) (:foreground "green" :bold t))
(((class color) (background dark)) (:foreground "green" :bold t)))
"Git mode face used for permission changes."
:group 'git)
@@ -664,9 +673,11 @@ Return the list of files that haven't been handled."
(ewoc-set-hf status
(format "Directory: %s\nBranch: %s\nHead: %s%s\n"
default-directory
(if (string-match "^refs/heads/" branch)
(substring branch (match-end 0))
branch)
(if branch
(if (string-match "^refs/heads/" branch)
(substring branch (match-end 0))
branch)
"none (detached HEAD)")
head
(if merge-heads
(concat "\nMerging: "

View File

@@ -231,6 +231,56 @@ def findUpstreamBranchPoint(head = "HEAD"):
return ["", settings]
def createOrUpdateBranchesFromOrigin(localRefPrefix = "refs/remotes/p4/", silent=True):
if not silent:
print ("Creating/updating branch(es) in %s based on origin branch(es)"
% localRefPrefix)
originPrefix = "origin/p4/"
for line in read_pipe_lines("git rev-parse --symbolic --remotes"):
line = line.strip()
if (not line.startswith(originPrefix)) or line.endswith("HEAD"):
continue
headName = line[len(originPrefix):]
remoteHead = localRefPrefix + headName
originHead = line
original = extractSettingsGitLog(extractLogMessageFromGitCommit(originHead))
if (not original.has_key('depot-paths')
or not original.has_key('change')):
continue
update = False
if not gitBranchExists(remoteHead):
if verbose:
print "creating %s" % remoteHead
update = True
else:
settings = extractSettingsGitLog(extractLogMessageFromGitCommit(remoteHead))
if settings.has_key('change') > 0:
if settings['depot-paths'] == original['depot-paths']:
originP4Change = int(original['change'])
p4Change = int(settings['change'])
if originP4Change > p4Change:
print ("%s (%s) is newer than %s (%s). "
"Updating p4 branch from origin."
% (originHead, originP4Change,
remoteHead, p4Change))
update = True
else:
print ("Ignoring: %s was imported from %s while "
"%s was imported from %s"
% (originHead, ','.join(original['depot-paths']),
remoteHead, ','.join(settings['depot-paths'])))
if update:
system("git update-ref %s %s" % (remoteHead, originHead))
def originP4BranchesExist():
return gitBranchExists("origin") or gitBranchExists("origin/p4") or gitBranchExists("origin/p4/master")
class Command:
def __init__(self):
self.usage = "usage: %prog [options]"
@@ -1041,53 +1091,6 @@ class P4Sync(Command):
for branch in branches.keys():
self.initialParents[self.refPrefix + branch] = branches[branch]
def createOrUpdateBranchesFromOrigin(self):
if not self.silent:
print ("Creating/updating branch(es) in %s based on origin branch(es)"
% self.refPrefix)
originPrefix = "origin/p4/"
for line in read_pipe_lines("git rev-parse --symbolic --remotes"):
line = line.strip()
if (not line.startswith(originPrefix)) or line.endswith("HEAD"):
continue
headName = line[len(originPrefix):]
remoteHead = self.refPrefix + headName
originHead = line
original = extractSettingsGitLog(extractLogMessageFromGitCommit(originHead))
if (not original.has_key('depot-paths')
or not original.has_key('change')):
continue
update = False
if not gitBranchExists(remoteHead):
if self.verbose:
print "creating %s" % remoteHead
update = True
else:
settings = extractSettingsGitLog(extractLogMessageFromGitCommit(remoteHead))
if settings.has_key('change') > 0:
if settings['depot-paths'] == original['depot-paths']:
originP4Change = int(original['change'])
p4Change = int(settings['change'])
if originP4Change > p4Change:
print ("%s (%s) is newer than %s (%s). "
"Updating p4 branch from origin."
% (originHead, originP4Change,
remoteHead, p4Change))
update = True
else:
print ("Ignoring: %s was imported from %s while "
"%s was imported from %s"
% (originHead, ','.join(original['depot-paths']),
remoteHead, ','.join(settings['depot-paths'])))
if update:
system("git update-ref %s %s" % (remoteHead, originHead))
def updateOptionDict(self, d):
option_keys = {}
if self.keepRepoPath:
@@ -1108,7 +1111,7 @@ class P4Sync(Command):
# map from branch depot path to parent branch
self.knownBranches = {}
self.initialParents = {}
self.hasOrigin = gitBranchExists("origin") or gitBranchExists("origin/p4") or gitBranchExists("origin/p4/master")
self.hasOrigin = originP4BranchesExist()
if not self.syncWithOrigin:
self.hasOrigin = False
@@ -1128,14 +1131,14 @@ class P4Sync(Command):
system("git update-ref %s refs/heads/p4" % self.branch)
system("git branch -D p4");
# create it /after/ importing, when master exists
if not gitBranchExists(self.refPrefix + "HEAD") and self.importIntoRemotes:
if not gitBranchExists(self.refPrefix + "HEAD") and self.importIntoRemotes and gitBranchExists(self.branch):
system("git symbolic-ref %sHEAD %s" % (self.refPrefix, self.branch))
# TODO: should always look at previous commits,
# merge with previous imports, if possible.
if args == []:
if self.hasOrigin:
self.createOrUpdateBranchesFromOrigin()
createOrUpdateBranchesFromOrigin(self.refPrefix, self.silent)
self.listExistingP4GitBranches()
if len(self.p4BranchesInGit) > 1:
@@ -1518,6 +1521,9 @@ class P4Branches(Command):
self.verbose = False
def run(self, args):
if originP4BranchesExist():
createOrUpdateBranchesFromOrigin()
cmdline = "git rev-parse --symbolic "
cmdline += " --remotes"

View File

@@ -24,9 +24,21 @@ git_dir=$(cd "$orig_git" 2>/dev/null &&
git rev-parse --git-dir 2>/dev/null) ||
die "\"$orig_git\" is not a git repository!"
if test "$git_dir" = ".git"
then
case "$git_dir" in
.git)
git_dir="$orig_git/.git"
;;
.)
git_dir=$orig_git
;;
esac
# don't link to a configured bare repository
isbare=$(git --git-dir="$git_dir" config --bool --get core.bare)
if test ztrue = z$isbare
then
die "\"$git_dir\" has core.bare set to true," \
" remove from \"$git_dir/config\" to use $0"
fi
# don't link to a workdir

View File

@@ -213,7 +213,7 @@ struct delta_index * create_delta_index(const void *buf, unsigned long bufsize)
entry = hash[i];
do {
struct index_entry *keep = entry;
int skip = hash_count[i] / HASH_LIMIT / 2;
int skip = hash_count[i] / HASH_LIMIT;
do {
entry = entry->next;
} while(--skip && entry);

4
diff.c
View File

@@ -2914,10 +2914,6 @@ static int diff_get_patch_id(struct diff_options *options, unsigned char *sha1)
fill_mmfile(&mf2, p->two) < 0)
return error("unable to read files to diff");
/* Maybe hash p->two? into the patch id? */
if (diff_filespec_is_binary(p->two))
continue;
len1 = remove_space(p->one->path, strlen(p->one->path));
len2 = remove_space(p->two->path, strlen(p->two->path));
if (p->one->mode == 0)

View File

@@ -8,10 +8,11 @@ Format of STDIN stream:
| new_tag
| reset_branch
| checkpoint
| progress
;
new_blob ::= 'blob' lf
mark?
mark?
file_content;
file_content ::= data;
@@ -23,7 +24,7 @@ Format of STDIN stream:
('from' sp (ref_str | hexsha1 | sha1exp_str | idnum) lf)?
('merge' sp (ref_str | hexsha1 | sha1exp_str | idnum) lf)*
file_change*
lf;
lf?;
commit_msg ::= data;
file_change ::= file_clr
@@ -42,33 +43,36 @@ Format of STDIN stream:
new_tag ::= 'tag' sp tag_str lf
'from' sp (ref_str | hexsha1 | sha1exp_str | idnum) lf
'tagger' sp name '<' email '>' when lf
'tagger' sp name '<' email '>' when lf
tag_msg;
tag_msg ::= data;
reset_branch ::= 'reset' sp ref_str lf
('from' sp (ref_str | hexsha1 | sha1exp_str | idnum) lf)?
lf;
lf?;
checkpoint ::= 'checkpoint' lf
lf;
lf?;
progress ::= 'progress' sp not_lf* lf
lf?;
# note: the first idnum in a stream should be 1 and subsequent
# idnums should not have gaps between values as this will cause
# the stream parser to reserve space for the gapped values. An
# idnum can be updated in the future to a new object by issuing
# idnum can be updated in the future to a new object by issuing
# a new mark directive with the old idnum.
#
#
mark ::= 'mark' sp idnum lf;
data ::= (delimited_data | exact_data)
lf;
lf?;
# note: delim may be any string but must not contain lf.
# data_line may contain any data but must not be exactly
# delim.
delimited_data ::= 'data' sp '<<' delim lf
(data_line lf)*
delim lf;
delim lf;
# note: declen indicates the length of binary_data in bytes.
# declen does not include the lf preceeding the binary data.
@@ -78,10 +82,10 @@ Format of STDIN stream:
# note: quoted strings are C-style quoting supporting \c for
# common escapes of 'c' (e..g \n, \t, \\, \") or \nnn where nnn
# is the signed byte value in octal. Note that the only
# is the signed byte value in octal. Note that the only
# characters which must actually be escaped to protect the
# stream formatting is: \, " and LF. Otherwise these values
# are UTF8.
# are UTF8.
#
ref_str ::= ref;
sha1exp_str ::= sha1exp;
@@ -104,9 +108,9 @@ Format of STDIN stream:
lf ::= # ASCII newline (LF) character;
# note: a colon (':') must precede the numerical value assigned to
# an idnum. This is to distinguish it from a ref or tag name as
# an idnum. This is to distinguish it from a ref or tag name as
# GIT does not permit ':' in ref or tag strings.
#
#
idnum ::= ':' bigint;
path ::= # GIT style file path, e.g. "a/b/c";
ref ::= # GIT ref name, e.g. "refs/heads/MOZ_GECKO_EXPERIMENT";
@@ -115,13 +119,24 @@ Format of STDIN stream:
hexsha1 ::= # SHA1 in hexadecimal format;
# note: name and email are UTF8 strings, however name must not
# contain '<' or lf and email must not contain any of the
# contain '<' or lf and email must not contain any of the
# following: '<', '>', lf.
#
#
name ::= # valid GIT author/committer name;
email ::= # valid GIT author/committer email;
ts ::= # time since the epoch in seconds, ascii base10 notation;
tz ::= # GIT style timezone;
# note: comments may appear anywhere in the input, except
# within a data command. Any form of the data command
# always escapes the related input from comment processing.
#
# In case it is not clear, the '#' that starts the comment
# must be the first character on that the line (an lf have
# preceeded it).
#
comment ::= '#' not_lf* lf;
not_lf ::= # Any byte that is not ASCII newline (LF);
*/
#include "builtin.h"
@@ -254,6 +269,13 @@ typedef enum {
WHENSPEC_NOW,
} whenspec_type;
struct recent_command
{
struct recent_command *prev;
struct recent_command *next;
char *buf;
};
/* Configured limits on output */
static unsigned long max_depth = 10;
static off_t max_packsize = (1LL << 32) - 1;
@@ -319,9 +341,120 @@ static struct tag *last_tag;
/* Input stream parsing */
static whenspec_type whenspec = WHENSPEC_RAW;
static struct strbuf command_buf;
static int unread_command_buf;
static struct recent_command cmd_hist = {&cmd_hist, &cmd_hist, NULL};
static struct recent_command *cmd_tail = &cmd_hist;
static struct recent_command *rc_free;
static unsigned int cmd_save = 100;
static uintmax_t next_mark;
static struct dbuf new_data;
static void write_branch_report(FILE *rpt, struct branch *b)
{
fprintf(rpt, "%s:\n", b->name);
fprintf(rpt, " status :");
if (b->active)
fputs(" active", rpt);
if (b->branch_tree.tree)
fputs(" loaded", rpt);
if (is_null_sha1(b->branch_tree.versions[1].sha1))
fputs(" dirty", rpt);
fputc('\n', rpt);
fprintf(rpt, " tip commit : %s\n", sha1_to_hex(b->sha1));
fprintf(rpt, " old tree : %s\n", sha1_to_hex(b->branch_tree.versions[0].sha1));
fprintf(rpt, " cur tree : %s\n", sha1_to_hex(b->branch_tree.versions[1].sha1));
fprintf(rpt, " commit clock: %" PRIuMAX "\n", b->last_commit);
fputs(" last pack : ", rpt);
if (b->pack_id < MAX_PACK_ID)
fprintf(rpt, "%u", b->pack_id);
fputc('\n', rpt);
fputc('\n', rpt);
}
static void write_crash_report(const char *err)
{
char *loc = git_path("fast_import_crash_%d", getpid());
FILE *rpt = fopen(loc, "w");
struct branch *b;
unsigned long lu;
struct recent_command *rc;
if (!rpt) {
error("can't write crash report %s: %s", loc, strerror(errno));
return;
}
fprintf(stderr, "fast-import: dumping crash report to %s\n", loc);
fprintf(rpt, "fast-import crash report:\n");
fprintf(rpt, " fast-import process: %d\n", getpid());
fprintf(rpt, " parent process : %d\n", getppid());
fprintf(rpt, " at %s\n", show_date(time(NULL), 0, DATE_LOCAL));
fputc('\n', rpt);
fputs("fatal: ", rpt);
fputs(err, rpt);
fputc('\n', rpt);
fputc('\n', rpt);
fputs("Most Recent Commands Before Crash\n", rpt);
fputs("---------------------------------\n", rpt);
for (rc = cmd_hist.next; rc != &cmd_hist; rc = rc->next) {
if (rc->next == &cmd_hist)
fputs("* ", rpt);
else
fputs(" ", rpt);
fputs(rc->buf, rpt);
fputc('\n', rpt);
}
fputc('\n', rpt);
fputs("Active Branch LRU\n", rpt);
fputs("-----------------\n", rpt);
fprintf(rpt, " active_branches = %lu cur, %lu max\n",
cur_active_branches,
max_active_branches);
fputc('\n', rpt);
fputs(" pos clock name\n", rpt);
fputs(" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n", rpt);
for (b = active_branches, lu = 0; b; b = b->active_next_branch)
fprintf(rpt, " %2lu) %6" PRIuMAX" %s\n",
++lu, b->last_commit, b->name);
fputc('\n', rpt);
fputs("Inactive Branches\n", rpt);
fputs("-----------------\n", rpt);
for (lu = 0; lu < branch_table_sz; lu++) {
for (b = branch_table[lu]; b; b = b->table_next_branch)
write_branch_report(rpt, b);
}
fputc('\n', rpt);
fputs("-------------------\n", rpt);
fputs("END OF CRASH REPORT\n", rpt);
fclose(rpt);
}
static NORETURN void die_nicely(const char *err, va_list params)
{
static int zombie;
char message[2 * PATH_MAX];
vsnprintf(message, sizeof(message), err, params);
fputs("fatal: ", stderr);
fputs(message, stderr);
fputc('\n', stderr);
if (!zombie) {
zombie = 1;
write_crash_report(message);
}
exit(128);
}
static void alloc_objects(unsigned int cnt)
{
@@ -524,8 +657,12 @@ static struct branch *new_branch(const char *name)
if (b)
die("Invalid attempt to create duplicate branch: %s", name);
if (check_ref_format(name))
switch (check_ref_format(name)) {
case 0: break; /* its valid */
case -2: break; /* valid, but too few '/', allow anyway */
default:
die("Branch name doesn't conform to GIT standards: %s", name);
}
b = pool_calloc(1, sizeof(struct branch));
b->name = pool_strdup(name);
@@ -1450,7 +1587,43 @@ static void dump_marks(void)
static void read_next_command(void)
{
read_line(&command_buf, stdin, '\n');
do {
if (unread_command_buf) {
unread_command_buf = 0;
if (command_buf.eof)
return;
} else {
struct recent_command *rc;
command_buf.buf = NULL;
read_line(&command_buf, stdin, '\n');
if (command_buf.eof)
return;
rc = rc_free;
if (rc)
rc_free = rc->next;
else {
rc = cmd_hist.next;
cmd_hist.next = rc->next;
cmd_hist.next->prev = &cmd_hist;
free(rc->buf);
}
rc->buf = command_buf.buf;
rc->prev = cmd_tail;
rc->next = cmd_hist.prev;
rc->prev->next = rc;
cmd_tail = rc;
}
} while (command_buf.buf[0] == '#');
}
static void skip_optional_lf(void)
{
int term_char = fgetc(stdin);
if (term_char != '\n' && term_char != EOF)
ungetc(term_char, stdin);
}
static void cmd_mark(void)
@@ -1476,19 +1649,15 @@ static void *cmd_data (size_t *size)
size_t sz = 8192, term_len = command_buf.len - 5 - 2;
length = 0;
buffer = xmalloc(sz);
command_buf.buf = NULL;
for (;;) {
read_next_command();
read_line(&command_buf, stdin, '\n');
if (command_buf.eof)
die("EOF in data (terminator '%s' not found)", term);
if (term_len == command_buf.len
&& !strcmp(term, command_buf.buf))
break;
if (sz < (length + command_buf.len)) {
sz = sz * 3 / 2 + 16;
if (sz < (length + command_buf.len))
sz = length + command_buf.len;
buffer = xrealloc(buffer, sz);
}
ALLOC_GROW(buffer, length + command_buf.len, sz);
memcpy(buffer + length,
command_buf.buf,
command_buf.len - 1);
@@ -1510,9 +1679,7 @@ static void *cmd_data (size_t *size)
}
}
if (fgetc(stdin) != '\n')
die("An lf did not trail the binary data as expected.");
skip_optional_lf();
*size = length;
return buffer;
}
@@ -1808,13 +1975,13 @@ static void cmd_from_existing(struct branch *b)
}
}
static void cmd_from(struct branch *b)
static int cmd_from(struct branch *b)
{
const char *from;
struct branch *s;
if (prefixcmp(command_buf.buf, "from "))
return;
return 0;
if (b->branch_tree.tree) {
release_tree_content_recursive(b->branch_tree.tree);
@@ -1849,6 +2016,7 @@ static void cmd_from(struct branch *b)
die("Invalid ref name or SHA1 expression: %s", from);
read_next_command();
return 1;
}
static struct hash_list *cmd_merge(unsigned int *count)
@@ -1933,10 +2101,8 @@ static void cmd_new_commit(void)
}
/* file_change* */
for (;;) {
if (1 == command_buf.len)
break;
else if (!prefixcmp(command_buf.buf, "M "))
while (!command_buf.eof && command_buf.len > 1) {
if (!prefixcmp(command_buf.buf, "M "))
file_change_m(b);
else if (!prefixcmp(command_buf.buf, "D "))
file_change_d(b);
@@ -1946,8 +2112,10 @@ static void cmd_new_commit(void)
file_change_cr(b, 0);
else if (!strcmp("deleteall", command_buf.buf))
file_change_deleteall(b);
else
die("Unsupported file_change: %s", command_buf.buf);
else {
unread_command_buf = 1;
break;
}
read_next_command();
}
@@ -2088,7 +2256,8 @@ static void cmd_reset_branch(void)
else
b = new_branch(sp);
read_next_command();
cmd_from(b);
if (!cmd_from(b) && command_buf.len > 1)
unread_command_buf = 1;
}
static void cmd_checkpoint(void)
@@ -2099,7 +2268,15 @@ static void cmd_checkpoint(void)
dump_tags();
dump_marks();
}
read_next_command();
skip_optional_lf();
}
static void cmd_progress(void)
{
fwrite(command_buf.buf, 1, command_buf.len - 1, stdout);
fputc('\n', stdout);
fflush(stdout);
skip_optional_lf();
}
static void import_marks(const char *input_file)
@@ -2142,7 +2319,7 @@ static const char fast_import_usage[] =
int main(int argc, const char **argv)
{
int i, show_stats = 1;
unsigned int i, show_stats = 1;
git_config(git_default_config);
alloc_objects(object_entry_alloc);
@@ -2196,8 +2373,14 @@ int main(int argc, const char **argv)
if (i != argc)
usage(fast_import_usage);
rc_free = pool_alloc(cmd_save * sizeof(*rc_free));
for (i = 0; i < (cmd_save - 1); i++)
rc_free[i].next = &rc_free[i + 1];
rc_free[cmd_save - 1].next = NULL;
prepare_packed_git();
start_packfile();
set_die_routine(die_nicely);
for (;;) {
read_next_command();
if (command_buf.eof)
@@ -2212,6 +2395,8 @@ int main(int argc, const char **argv)
cmd_reset_branch();
else if (!strcmp("checkpoint", command_buf.buf))
cmd_checkpoint();
else if (!prefixcmp(command_buf.buf, "progress "))
cmd_progress();
else
die("Unsupported command: %s", command_buf.buf);
}

View File

@@ -2,8 +2,10 @@
#
# Copyright (c) 2005, 2006 Junio C Hamano
USAGE='[--signoff] [--dotest=<dir>] [--utf8 | --no-utf8] [--binary] [--3way]
[--interactive] [--whitespace=<option>] [-C<n>] [-p<n>] <mbox>...
USAGE='[--signoff] [--dotest=<dir>] [--keep] [--utf8 | --no-utf8]
[--3way] [--interactive] [--binary]
[--whitespace=<option>] [-C<n>] [-p<n>]
<mbox>|<Maildir>...
or, when resuming [--skip | --resolved]'
. git-sh-setup
set_reflog_action am

View File

@@ -99,6 +99,7 @@ origin_override=
use_separate_remote=t
depth=
no_progress=
local_explicitly_asked_for=
test -t 1 || no_progress=--no-progress
while
case "$#,$1" in
@@ -109,6 +110,7 @@ while
*,--na|*,--nak|*,--nake|*,--naked|\
*,-b|*,--b|*,--ba|*,--bar|*,--bare) bare=yes ;;
*,-l|*,--l|*,--lo|*,--loc|*,--loca|*,--local)
local_explicitly_asked_for=yes
use_local_hardlink=yes ;;
*,--no-h|*,--no-ha|*,--no-har|*,--no-hard|*,--no-hardl|\
*,--no-hardli|*,--no-hardlin|*,--no-hardlink|*,--no-hardlinks)
@@ -281,7 +283,8 @@ yes)
then
rm -f "$GIT_DIR/objects/sample"
l=l
else
elif test -n "$local_explicitly_asked_for"
then
echo >&2 "Warning: -l asked but cannot hardlink to $repo"
fi
fi &&

View File

@@ -49,10 +49,11 @@ run_status () {
export GIT_INDEX_FILE
fi
case "$status_only" in
t) color= ;;
*) color=--nocolor ;;
esac
if test "$status_only" = "t" -o "$use_status_color" = "t"; then
color=
else
color=--nocolor
fi
git runstatus ${color} \
${verbose:+--verbose} \
${amend:+--amend} \
@@ -556,6 +557,7 @@ fi
if [ "$?" != "0" -a ! -f "$GIT_DIR/MERGE_HEAD" -a -z "$amend" ]
then
rm -f "$GIT_DIR/COMMIT_EDITMSG" "$GIT_DIR/SQUASH_MSG"
use_status_color=t
run_status
exit 1
fi

View File

@@ -8,7 +8,7 @@
# a new branch. You can specify a number of filters to modify the commits,
# files and trees.
USAGE="git-filter-branch [-d TEMPDIR] [FILTERS] DESTBRANCH [REV-RANGE]"
USAGE="git-filter-branch [-d TEMPDIR] [FILTERS] [REV-RANGE]"
. git-sh-setup
warn () {

View File

@@ -60,54 +60,6 @@ if {![catch {set _verbose $env(GITGUI_VERBOSE)}]} {
}
}
######################################################################
##
## configure our library
set oguilib {@@GITGUI_LIBDIR@@}
set oguirel {@@GITGUI_RELATIVE@@}
if {$oguirel eq {1}} {
set oguilib [file dirname [file dirname [file normalize $argv0]]]
set oguilib [file join $oguilib share git-gui lib]
} elseif {[string match @@* $oguirel]} {
set oguilib [file join [file dirname [file normalize $argv0]] lib]
}
set idx [file join $oguilib tclIndex]
if {[catch {set fd [open $idx r]} err]} {
catch {wm withdraw .}
tk_messageBox \
-icon error \
-type ok \
-title "git-gui: fatal error" \
-message $err
exit 1
}
if {[gets $fd] eq {# Autogenerated by git-gui Makefile}} {
set idx [list]
while {[gets $fd n] >= 0} {
if {$n ne {} && ![string match #* $n]} {
lappend idx $n
}
}
} else {
set idx {}
}
close $fd
if {$idx ne {}} {
set loaded [list]
foreach p $idx {
if {[lsearch -exact $loaded $p] >= 0} continue
source [file join $oguilib $p]
lappend loaded $p
}
unset loaded p
} else {
set auto_path [concat [list $oguilib] $auto_path]
}
unset -nocomplain oguirel idx fd
######################################################################
##
## read only globals
@@ -532,7 +484,11 @@ if {$_git eq {}} {
if {[catch {set _git_version [git --version]} err]} {
catch {wm withdraw .}
error_popup "Cannot determine Git version:
tk_messageBox \
-icon error \
-type ok \
-title "git-gui: fatal error" \
-message "Cannot determine Git version:
$err
@@ -541,7 +497,11 @@ $err
}
if {![regsub {^git version } $_git_version {} _git_version]} {
catch {wm withdraw .}
error_popup "Cannot parse Git version string:\n\n$_git_version"
tk_messageBox \
-icon error \
-type ok \
-title "git-gui: fatal error" \
-message "Cannot parse Git version string:\n\n$_git_version"
exit 1
}
@@ -619,7 +579,11 @@ proc git-version {args} {
if {[git-version < 1.5]} {
catch {wm withdraw .}
error_popup "[appname] requires Git 1.5.0 or later.
tk_messageBox \
-icon error \
-type ok \
-title "git-gui: fatal error" \
-message "[appname] requires Git 1.5.0 or later.
You are using [git-version]:
@@ -627,6 +591,54 @@ You are using [git-version]:
exit 1
}
######################################################################
##
## configure our library
set oguilib {@@GITGUI_LIBDIR@@}
set oguirel {@@GITGUI_RELATIVE@@}
if {$oguirel eq {1}} {
set oguilib [file dirname [file dirname [file normalize $argv0]]]
set oguilib [file join $oguilib share git-gui lib]
} elseif {[string match @@* $oguirel]} {
set oguilib [file join [file dirname [file normalize $argv0]] lib]
}
set idx [file join $oguilib tclIndex]
if {[catch {set fd [open $idx r]} err]} {
catch {wm withdraw .}
tk_messageBox \
-icon error \
-type ok \
-title "git-gui: fatal error" \
-message $err
exit 1
}
if {[gets $fd] eq {# Autogenerated by git-gui Makefile}} {
set idx [list]
while {[gets $fd n] >= 0} {
if {$n ne {} && ![string match #* $n]} {
lappend idx $n
}
}
} else {
set idx {}
}
close $fd
if {$idx ne {}} {
set loaded [list]
foreach p $idx {
if {[lsearch -exact $loaded $p] >= 0} continue
source [file join $oguilib $p]
lappend loaded $p
}
unset loaded p
} else {
set auto_path [concat [list $oguilib] $auto_path]
}
unset -nocomplain oguirel idx fd
######################################################################
##
## feature option selection
@@ -691,7 +703,15 @@ if {![file isdirectory $_gitdir]} {
error_popup "Git directory not found:\n\n$_gitdir"
exit 1
}
if {![is_enabled bare]} {
if {$_prefix ne {}} {
regsub -all {[^/]+/} $_prefix ../ cdup
if {[catch {cd $cdup} err]} {
catch {wm withdraw .}
error_popup "Cannot move to top of working directory:\n\n$err"
exit 1
}
unset cdup
} elseif {![is_enabled bare]} {
if {[lindex [file split $_gitdir] end] ne {.git}} {
catch {wm withdraw .}
error_popup "Cannot use funny .git directory:\n\n$_gitdir"
@@ -726,6 +746,7 @@ set empty_tree {}
set current_branch {}
set is_detached 0
set current_diff_path {}
set is_3way_diff 0
set selected_commit_type new
######################################################################
@@ -1348,6 +1369,9 @@ unset i
proc bind_button3 {w cmd} {
bind $w <Any-Button-3> $cmd
if {[is_MacOSX]} {
# Mac OS X sends Button-2 on right click through three-button mouse,
# or through trackpad right-clicking (two-finger touch + click).
bind $w <Any-Button-2> $cmd
bind $w <Control-Button-1> $cmd
}
}
@@ -1933,6 +1957,12 @@ if {$browser ne {}} {
}
unset browser doc_path doc_url
set root_exists 0
bind . <Visibility> {
bind . <Visibility> {}
set root_exists 1
}
# -- Standard bindings
#
wm protocol . WM_DELETE_WINDOW do_quit
@@ -2407,21 +2437,26 @@ $ctxm add separator
$ctxm add command -label {Options...} \
-command do_options
proc popup_diff_menu {ctxm x y X Y} {
global current_diff_path file_states
set ::cursorX $x
set ::cursorY $y
if {$::ui_index eq $::current_diff_side} {
$ctxm entryconf $::ui_diff_applyhunk \
-state normal \
-label {Unstage Hunk From Commit}
} elseif {{_O} eq [lindex $::file_states($::current_diff_path) 0]} {
$ctxm entryconf $::ui_diff_applyhunk \
-state disabled \
-label {Stage Hunk For Commit}
set s normal
set l "Unstage Hunk From Commit"
} else {
$ctxm entryconf $::ui_diff_applyhunk \
-state normal \
-label {Stage Hunk For Commit}
if {$current_diff_path eq {}
|| ![info exists file_states($current_diff_path)]
|| {_O} eq [lindex $file_states($current_diff_path) 0]} {
set s disabled
} else {
set s normal
}
set l "Stage Hunk For Commit"
}
if {$::is_3way_diff} {
set s disabled
}
$ctxm entryconf $::ui_diff_applyhunk -state $s -label $l
tk_popup $ctxm $X $Y
}
bind_button3 $ui_diff [list popup_diff_menu $ctxm %x %y %X %Y]

View File

@@ -148,11 +148,12 @@ proc make_toplevel {t w args} {
}
}
if {[winfo ismapped .]} {
if {$::root_exists || [winfo ismapped .]} {
regsub -all {::} $this {__} w
set top .$w
set pfx $top
toplevel $top
set ::root_exists 1
} else {
set top .
set pfx {}

View File

@@ -114,7 +114,7 @@ method _start {} {
lappend cmd --strategy=recursive
lappend cmd [git fmt-merge-msg <[gitdir FETCH_HEAD]]
lappend cmd HEAD
lappend cmd $cmit
lappend cmd $name
set msg "Merging $current_branch and $stitle"
ui_status "$msg..."

View File

@@ -19,10 +19,12 @@ LF='
all_strategies='recur recursive octopus resolve stupid ours subtree'
default_twohead_strategies='recursive'
default_octopus_strategies='octopus'
no_trivial_merge_strategies='ours subtree'
no_fast_forward_strategies='subtree ours'
no_trivial_strategies='recursive recur subtree ours'
use_strategies=
index_merge=t
allow_fast_forward=t
allow_trivial_merge=t
dropsave() {
rm -f -- "$GIT_DIR/MERGE_HEAD" "$GIT_DIR/MERGE_MSG" \
@@ -265,11 +267,20 @@ esac
for s in $use_strategies
do
for nt in $no_trivial_merge_strategies
for ss in $no_fast_forward_strategies
do
case " $s " in
*" $nt "*)
index_merge=f
*" $ss "*)
allow_fast_forward=f
break
;;
esac
done
for ss in $no_trivial_strategies
do
case " $s " in
*" $ss "*)
allow_trivial_merge=f
break
;;
esac
@@ -286,10 +297,7 @@ case "$#" in
esac
echo "$head" >"$GIT_DIR/ORIG_HEAD"
case "$index_merge,$#,$common,$no_commit" in
f,*)
# We've been told not to try anything clever. Skip to real merge.
;;
case "$allow_fast_forward,$#,$common,$no_commit" in
?,*,'',*)
# No common ancestors found. We need a real merge.
;;
@@ -299,7 +307,7 @@ f,*)
finish_up_to_date "Already up-to-date."
exit 0
;;
?,1,"$head",*)
t,1,"$head",*)
# Again the most common case of merging one remote.
echo "Updating $(git rev-parse --short $head)..$(git rev-parse --short $1)"
git update-index --refresh 2>/dev/null
@@ -322,11 +330,8 @@ f,*)
# We are not doing octopus, not fast forward, and have only
# one common.
git update-index --refresh 2>/dev/null
case " $use_strategies " in
*' recursive '*|*' recur '*)
: run merge later
;;
*)
case "$allow_trivial_merge" in
t)
# See if it is really trivial.
git var GIT_COMMITTER_IDENT >/dev/null || exit
echo "Trying really trivial in-index merge..."

View File

@@ -96,13 +96,14 @@ die_abort () {
}
pick_one () {
case "$1" in -n) sha1=$2 ;; *) sha1=$1 ;; esac
no_ff=
case "$1" in -n) sha1=$2; no_ff=t ;; *) sha1=$1 ;; esac
output git rev-parse --verify $sha1 || die "Invalid commit name: $sha1"
test -d "$REWRITTEN" &&
pick_one_preserving_merges "$@" && return
parent_sha1=$(git rev-parse --verify $sha1^ 2>/dev/null)
current_sha1=$(git rev-parse --verify HEAD)
if test $current_sha1 = $parent_sha1; then
if test $no_ff$current_sha1 = $parent_sha1; then
output git reset --hard $sha1
test "a$1" = a-n && output git reset --soft $current_sha1
sha1=$(git rev-parse --short $sha1)

View File

@@ -21,8 +21,11 @@ use warnings;
use Term::ReadLine;
use Getopt::Long;
use Data::Dumper;
use Term::ANSIColor;
use Git;
$SIG{INT} = sub { print color("reset"), "\n"; exit };
package FakeTerm;
sub new {
my ($class, $reason) = @_;

View File

@@ -313,7 +313,7 @@ case "$add,$init,$update,$status,$cached" in
,,1,,)
modules_update "$@"
;;
,,,1,*)
,,,*,*)
modules_list "$@"
;;
*)

View File

@@ -77,11 +77,12 @@ my %fc_opts = ( 'follow-parent|follow!' => \$Git::SVN::_follow_parent,
\$Git::SVN::_repack_flags,
%remote_opts );
my ($_trunk, $_tags, $_branches);
my ($_trunk, $_tags, $_branches, $_stdlayout);
my %icv;
my %init_opts = ( 'template=s' => \$_template, 'shared:s' => \$_shared,
'trunk|T=s' => \$_trunk, 'tags|t=s' => \$_tags,
'branches|b=s' => \$_branches, 'prefix=s' => \$_prefix,
'stdlayout|s' => \$_stdlayout,
'minimize-url|m' => \$Git::SVN::_minimize_url,
'no-metadata' => sub { $icv{noMetadata} = 1 },
'use-svm-props' => sub { $icv{useSvmProps} = 1 },
@@ -292,7 +293,8 @@ sub init_subdir {
sub cmd_clone {
my ($url, $path) = @_;
if (!defined $path &&
(defined $_trunk || defined $_branches || defined $_tags) &&
(defined $_trunk || defined $_branches || defined $_tags ||
defined $_stdlayout) &&
$url !~ m#^[a-z\+]+://#) {
$path = $url;
}
@@ -302,6 +304,11 @@ sub cmd_clone {
}
sub cmd_init {
if (defined $_stdlayout) {
$_trunk = 'trunk' if (!defined $_trunk);
$_tags = 'tags' if (!defined $_tags);
$_branches = 'branches' if (!defined $_branches);
}
if (defined $_trunk || defined $_branches || defined $_tags) {
return cmd_multi_init(@_);
}
@@ -370,6 +377,7 @@ sub cmd_dcommit {
$head ||= 'HEAD';
my @refs;
my ($url, $rev, $uuid, $gs) = working_head_info($head, \@refs);
print "Committing to $url ...\n";
unless ($gs) {
die "Unable to determine upstream SVN information from ",
"$head history\n";

9
git.c
View File

@@ -4,7 +4,7 @@
#include "quote.h"
const char git_usage_string[] =
"git [--version] [--exec-path[=GIT_EXEC_PATH]] [-p|--paginate] [--bare] [--git-dir=GIT_DIR] [--work-tree=GIT_WORK_TREE] [--help] COMMAND [ARGS]";
"git [--version] [--exec-path[=GIT_EXEC_PATH]] [-p|--paginate|--no-pager] [--bare] [--git-dir=GIT_DIR] [--work-tree=GIT_WORK_TREE] [--help] COMMAND [ARGS]";
static void prepend_to_path(const char *dir, int len)
{
@@ -62,6 +62,10 @@ static int handle_options(const char*** argv, int* argc, int* envchanged)
}
} else if (!strcmp(cmd, "-p") || !strcmp(cmd, "--paginate")) {
setup_pager();
} else if (!strcmp(cmd, "--no-pager")) {
setenv("GIT_PAGER", "cat", 1);
if (envchanged)
*envchanged = 1;
} else if (!strcmp(cmd, "--git-dir")) {
if (*argc < 2) {
fprintf(stderr, "No directory given for --git-dir.\n" );
@@ -93,7 +97,8 @@ static int handle_options(const char*** argv, int* argc, int* envchanged)
*envchanged = 1;
} else if (!strcmp(cmd, "--bare")) {
static char git_dir[PATH_MAX+1];
setenv(GIT_DIR_ENVIRONMENT, getcwd(git_dir, sizeof(git_dir)), 1);
is_bare_repository_cfg = 1;
setenv(GIT_DIR_ENVIRONMENT, getcwd(git_dir, sizeof(git_dir)), 0);
if (envchanged)
*envchanged = 1;
} else {

271
gitk
View File

@@ -519,6 +519,7 @@ proc makewindow {} {
global textfont mainfont uifont tabstop
global findtype findtypemenu findloc findstring fstring geometry
global entries sha1entry sha1string sha1but
global diffcontextstring diffcontext
global maincursor textcursor curtextcursor
global rowctxmenu fakerowmenu mergemax wrapcomment
global highlight_files gdttype
@@ -532,6 +533,7 @@ proc makewindow {} {
menu .bar.file
.bar.file add command -label "Update" -command updatecommits
.bar.file add command -label "Reread references" -command rereadrefs
.bar.file add command -label "List references" -command showrefs
.bar.file add command -label "Quit" -command doquit
.bar.file configure -font $uifont
menu .bar.edit
@@ -733,7 +735,17 @@ proc makewindow {} {
-command changediffdisp -variable diffelide -value {0 1}
radiobutton .bleft.mid.new -text "New version" \
-command changediffdisp -variable diffelide -value {1 0}
label .bleft.mid.labeldiffcontext -text " Lines of context: " \
-font $uifont
pack .bleft.mid.diff .bleft.mid.old .bleft.mid.new -side left
spinbox .bleft.mid.diffcontext -width 5 -font $textfont \
-from 1 -increment 1 -to 10000000 \
-validate all -validatecommand "diffcontextvalidate %P" \
-textvariable diffcontextstring
.bleft.mid.diffcontext set $diffcontext
trace add variable diffcontextstring write diffcontextchange
lappend entries .bleft.mid.diffcontext
pack .bleft.mid.labeldiffcontext .bleft.mid.diffcontext -side left
set ctext .bleft.ctext
text $ctext -background $bgcolor -foreground $fgcolor \
-tabs "[expr {$tabstop * $charspc}]" \
@@ -1001,8 +1013,8 @@ proc savestuff {w} {
global stuffsaved findmergefiles maxgraphpct
global maxwidth showneartags showlocalchanges
global viewname viewfiles viewargs viewperm nextviewnum
global cmitmode wrapcomment
global colors bgcolor fgcolor diffcolors selectbgcolor
global cmitmode wrapcomment datetimeformat
global colors bgcolor fgcolor diffcolors diffcontext selectbgcolor
if {$stuffsaved} return
if {![winfo viewable .]} return
@@ -1019,10 +1031,12 @@ proc savestuff {w} {
puts $f [list set wrapcomment $wrapcomment]
puts $f [list set showneartags $showneartags]
puts $f [list set showlocalchanges $showlocalchanges]
puts $f [list set datetimeformat $datetimeformat]
puts $f [list set bgcolor $bgcolor]
puts $f [list set fgcolor $fgcolor]
puts $f [list set colors $colors]
puts $f [list set diffcolors $diffcolors]
puts $f [list set diffcontext $diffcontext]
puts $f [list set selectbgcolor $selectbgcolor]
puts $f "set geometry(main) [wm geometry .]"
@@ -1454,6 +1468,38 @@ image create bitmap tri-dn -background black -foreground blue -data {
0x00, 0x00};
}
image create bitmap reficon-T -background black -foreground yellow -data {
#define tagicon_width 13
#define tagicon_height 9
static unsigned char tagicon_bits[] = {
0x00, 0x00, 0x00, 0x00, 0xf0, 0x07, 0xf8, 0x07,
0xfc, 0x07, 0xf8, 0x07, 0xf0, 0x07, 0x00, 0x00, 0x00, 0x00};
} -maskdata {
#define tagicon-mask_width 13
#define tagicon-mask_height 9
static unsigned char tagicon-mask_bits[] = {
0x00, 0x00, 0xf0, 0x0f, 0xf8, 0x0f, 0xfc, 0x0f,
0xfe, 0x0f, 0xfc, 0x0f, 0xf8, 0x0f, 0xf0, 0x0f, 0x00, 0x00};
}
set rectdata {
#define headicon_width 13
#define headicon_height 9
static unsigned char headicon_bits[] = {
0x00, 0x00, 0x00, 0x00, 0xf8, 0x07, 0xf8, 0x07,
0xf8, 0x07, 0xf8, 0x07, 0xf8, 0x07, 0x00, 0x00, 0x00, 0x00};
}
set rectmask {
#define headicon-mask_width 13
#define headicon-mask_height 9
static unsigned char headicon-mask_bits[] = {
0x00, 0x00, 0xfc, 0x0f, 0xfc, 0x0f, 0xfc, 0x0f,
0xfc, 0x0f, 0xfc, 0x0f, 0xfc, 0x0f, 0xfc, 0x0f, 0x00, 0x00};
}
image create bitmap reficon-H -background black -foreground green \
-data $rectdata -maskdata $rectmask
image create bitmap reficon-o -background black -foreground "#ddddff" \
-data $rectdata -maskdata $rectmask
proc init_flist {first} {
global cflist cflist_top selectedline difffilestart
@@ -1976,6 +2022,7 @@ proc showview {n} {
} elseif {$numcommits == 0} {
show_status "No commits selected"
}
run refill_reflist
}
# Stuff relating to the highlighting facility
@@ -2739,13 +2786,22 @@ proc layoutmore {tmax allread} {
proc showstuff {canshow last} {
global numcommits commitrow pending_select selectedline curview
global lookingforhead mainheadid displayorder selectfirst
global lastscrollset
global lastscrollset commitinterest
if {$numcommits == 0} {
global phase
set phase "incrdraw"
allcanvs delete all
}
for {set l $numcommits} {$l < $canshow} {incr l} {
set id [lindex $displayorder $l]
if {[info exists commitinterest($id)]} {
foreach script $commitinterest($id) {
eval [string map [list "%I" $id] $script]
}
unset commitinterest($id)
}
}
set r0 $numcommits
set prev $numcommits
set numcommits $canshow
@@ -4472,6 +4528,7 @@ proc selectline {l isnew} {
$canv delete hover
normalline
cancel_next_highlight
unsel_reflist
if {$l < 0 || $l >= $numcommits} return
set y [expr {$canvy0 + $l * $linespc}]
set ymax [lindex [$canv cget -scrollregion] 3]
@@ -5053,12 +5110,29 @@ proc gettreediffline {gdtf ids} {
return 0
}
# empty string or positive integer
proc diffcontextvalidate {v} {
return [regexp {^(|[1-9][0-9]*)$} $v]
}
proc diffcontextchange {n1 n2 op} {
global diffcontextstring diffcontext
if {[string is integer -strict $diffcontextstring]} {
if {$diffcontextstring > 0} {
set diffcontext $diffcontextstring
reselectline
}
}
}
proc getblobdiffs {ids} {
global diffopts blobdifffd diffids env
global diffinhdr treediffs
global diffcontext
set env(GIT_DIFF_OPTS) $diffopts
if {[catch {set bdf [open [diffcmd $ids {-p -C --no-commit-id}] r]} err]} {
if {[catch {set bdf [open [diffcmd $ids "-p -C --no-commit-id -U$diffcontext"] r]} err]} {
puts "error getting diffs: $err"
return
}
@@ -5117,8 +5191,8 @@ proc getblobdiffline {bdf ids} {
# the middle char will be a space, and the two bits either
# side will be a/name and b/name, or "a/name" and "b/name".
# If the name has changed we'll get "rename from" and
# "rename to" lines following this, and we'll use them
# to get the filenames.
# "rename to" or "copy from" and "copy to" lines following this,
# and we'll use them to get the filenames.
# This complexity is necessary because spaces in the filename(s)
# don't get escaped.
set l [string length $line]
@@ -5142,8 +5216,9 @@ proc getblobdiffline {bdf ids} {
set diffinhdr 0
} elseif {$diffinhdr} {
if {![string compare -length 12 "rename from " $line]} {
set fname [string range $line 12 end]
if {![string compare -length 12 "rename from " $line] ||
![string compare -length 10 "copy from " $line]} {
set fname [string range $line [expr 6 + [string first " from " $line] ] end]
if {[string index $fname 0] eq "\""} {
set fname [lindex $fname 0]
}
@@ -5151,8 +5226,9 @@ proc getblobdiffline {bdf ids} {
if {$i >= 0} {
setinlist difffilestart $i $curdiffstart
}
} elseif {![string compare -length 10 $line "rename to "]} {
set fname [string range $line 10 end]
} elseif {![string compare -length 10 $line "rename to "] ||
![string compare -length 8 $line "copy to "]} {
set fname [string range $line [expr 4 + [string first " to " $line] ] end]
if {[string index $fname 0] eq "\""} {
set fname [lindex $fname 0]
}
@@ -5383,7 +5459,7 @@ proc redisplay {} {
}
proc incrfont {inc} {
global mainfont textfont ctext canv phase cflist
global mainfont textfont ctext canv phase cflist showrefstop
global charspc tabstop
global stopped entries
unmarkmatches
@@ -5399,6 +5475,9 @@ proc incrfont {inc} {
if {$phase eq "getcommits"} {
$canv itemconf textitems -font $mainfont
}
if {[info exists showrefstop] && [winfo exists $showrefstop]} {
$showrefstop.list conf -font $mainfont
}
redisplay
}
@@ -5857,6 +5936,8 @@ proc domktag {} {
lappend idtags($id) $tag
redrawtags $id
addedtag $id
dispneartags 0
run refill_reflist
}
proc redrawtags {id} {
@@ -5998,6 +6079,7 @@ proc mkbrgo {top} {
notbusy newbranch
redrawtags $id
dispneartags 0
run refill_reflist
}
}
@@ -6169,7 +6251,7 @@ proc cobranch {} {
proc rmbranch {} {
global headmenuid headmenuhead mainhead
global headids idheads
global idheads
set head $headmenuhead
set id $headmenuid
@@ -6179,7 +6261,7 @@ proc rmbranch {} {
return
}
set dheads [descheads $id]
if {$dheads eq $headids($head)} {
if {[llength $dheads] == 1 && $idheads($dheads) eq $head} {
# the stuff on this branch isn't on any other branch
if {![confirm_popup "The commits on branch $head aren't on any other\
branch.\nReally delete branch $head?"]} return
@@ -6196,6 +6278,163 @@ proc rmbranch {} {
redrawtags $id
notbusy rmbranch
dispneartags 0
run refill_reflist
}
# Display a list of tags and heads
proc showrefs {} {
global showrefstop bgcolor fgcolor selectbgcolor mainfont
global bglist fglist uifont reflistfilter reflist maincursor
set top .showrefs
set showrefstop $top
if {[winfo exists $top]} {
raise $top
refill_reflist
return
}
toplevel $top
wm title $top "Tags and heads: [file tail [pwd]]"
text $top.list -background $bgcolor -foreground $fgcolor \
-selectbackground $selectbgcolor -font $mainfont \
-xscrollcommand "$top.xsb set" -yscrollcommand "$top.ysb set" \
-width 30 -height 20 -cursor $maincursor \
-spacing1 1 -spacing3 1 -state disabled
$top.list tag configure highlight -background $selectbgcolor
lappend bglist $top.list
lappend fglist $top.list
scrollbar $top.ysb -command "$top.list yview" -orient vertical
scrollbar $top.xsb -command "$top.list xview" -orient horizontal
grid $top.list $top.ysb -sticky nsew
grid $top.xsb x -sticky ew
frame $top.f
label $top.f.l -text "Filter: " -font $uifont
entry $top.f.e -width 20 -textvariable reflistfilter -font $uifont
set reflistfilter "*"
trace add variable reflistfilter write reflistfilter_change
pack $top.f.e -side right -fill x -expand 1
pack $top.f.l -side left
grid $top.f - -sticky ew -pady 2
button $top.close -command [list destroy $top] -text "Close" \
-font $uifont
grid $top.close -
grid columnconfigure $top 0 -weight 1
grid rowconfigure $top 0 -weight 1
bind $top.list <1> {break}
bind $top.list <B1-Motion> {break}
bind $top.list <ButtonRelease-1> {sel_reflist %W %x %y; break}
set reflist {}
refill_reflist
}
proc sel_reflist {w x y} {
global showrefstop reflist headids tagids otherrefids
if {![winfo exists $showrefstop]} return
set l [lindex [split [$w index "@$x,$y"] "."] 0]
set ref [lindex $reflist [expr {$l-1}]]
set n [lindex $ref 0]
switch -- [lindex $ref 1] {
"H" {selbyid $headids($n)}
"T" {selbyid $tagids($n)}
"o" {selbyid $otherrefids($n)}
}
$showrefstop.list tag add highlight $l.0 "$l.0 lineend"
}
proc unsel_reflist {} {
global showrefstop
if {![info exists showrefstop] || ![winfo exists $showrefstop]} return
$showrefstop.list tag remove highlight 0.0 end
}
proc reflistfilter_change {n1 n2 op} {
global reflistfilter
after cancel refill_reflist
after 200 refill_reflist
}
proc refill_reflist {} {
global reflist reflistfilter showrefstop headids tagids otherrefids
global commitrow curview commitinterest
if {![info exists showrefstop] || ![winfo exists $showrefstop]} return
set refs {}
foreach n [array names headids] {
if {[string match $reflistfilter $n]} {
if {[info exists commitrow($curview,$headids($n))]} {
lappend refs [list $n H]
} else {
set commitinterest($headids($n)) {run refill_reflist}
}
}
}
foreach n [array names tagids] {
if {[string match $reflistfilter $n]} {
if {[info exists commitrow($curview,$tagids($n))]} {
lappend refs [list $n T]
} else {
set commitinterest($tagids($n)) {run refill_reflist}
}
}
}
foreach n [array names otherrefids] {
if {[string match $reflistfilter $n]} {
if {[info exists commitrow($curview,$otherrefids($n))]} {
lappend refs [list $n o]
} else {
set commitinterest($otherrefids($n)) {run refill_reflist}
}
}
}
set refs [lsort -index 0 $refs]
if {$refs eq $reflist} return
# Update the contents of $showrefstop.list according to the
# differences between $reflist (old) and $refs (new)
$showrefstop.list conf -state normal
$showrefstop.list insert end "\n"
set i 0
set j 0
while {$i < [llength $reflist] || $j < [llength $refs]} {
if {$i < [llength $reflist]} {
if {$j < [llength $refs]} {
set cmp [string compare [lindex $reflist $i 0] \
[lindex $refs $j 0]]
if {$cmp == 0} {
set cmp [string compare [lindex $reflist $i 1] \
[lindex $refs $j 1]]
}
} else {
set cmp -1
}
} else {
set cmp 1
}
switch -- $cmp {
-1 {
$showrefstop.list delete "[expr {$j+1}].0" "[expr {$j+2}].0"
incr i
}
0 {
incr i
incr j
}
1 {
set l [expr {$j + 1}]
$showrefstop.list image create $l.0 -align baseline \
-image reficon-[lindex $refs $j 1] -padx 2
$showrefstop.list insert $l.1 "[lindex $refs $j 0]\n"
incr j
}
}
}
set reflist $refs
# delete last newline
$showrefstop.list delete end-2c end-1c
$showrefstop.list conf -state disabled
}
# Stuff for finding nearby tags
@@ -7093,6 +7332,7 @@ proc rereadrefs {} {
redrawtags $id
}
}
run refill_reflist
}
proc listrefs {id} {
@@ -7313,8 +7553,9 @@ proc prefsok {} {
}
proc formatdate {d} {
global datetimeformat
if {$d ne {}} {
set d [clock format $d -format "%Y-%m-%d %H:%M:%S"]
set d [clock format $d -format $datetimeformat]
}
return $d
}
@@ -7627,11 +7868,13 @@ set showneartags 1
set maxrefs 20
set maxlinelen 200
set showlocalchanges 1
set datetimeformat "%Y-%m-%d %H:%M:%S"
set colors {green red blue magenta darkgrey brown orange}
set bgcolor white
set fgcolor black
set diffcolors {red "#00a000" blue}
set diffcontext 3
set selectbgcolor gray85
catch {source ~/.gitk}

View File

@@ -430,7 +430,7 @@ div.search {
font-size: 100%;
font-weight: normal;
margin: 4px 8px;
position: absolute;
float: right;
top: 56px;
right: 12px
}

View File

@@ -471,9 +471,6 @@ if (defined $searchtype) {
our $searchtext = $cgi->param('s');
our $search_regexp;
if (defined $searchtext) {
if ($searchtype ne 'grep' and $searchtype ne 'pickaxe' and $searchtext =~ m/[^a-zA-Z0-9_\.\/\-\+\:\@ ]/) {
die_error(undef, "Invalid search parameter");
}
if (length($searchtext) < 2) {
die_error(undef, "At least two characters are required for search parameter");
}
@@ -3422,7 +3419,7 @@ sub git_project_list_body {
"<td>" . $cgi->a({-href => href(project=>$pr->{'path'}, action=>"summary"),
-class => "list", -title => $pr->{'descr_long'}},
esc_html($pr->{'descr'})) . "</td>\n" .
"<td><i>" . chop_str($pr->{'owner'}, 15) . "</i></td>\n";
"<td><i>" . esc_html(chop_str($pr->{'owner'}, 15)) . "</i></td>\n";
print "<td class=\"". age_class($pr->{'age'}) . "\">" .
(defined $pr->{'age_string'} ? $pr->{'age_string'} : "No commits") . "</td>\n" .
"<td class=\"link\">" .
@@ -3798,7 +3795,7 @@ sub git_summary {
print "<div class=\"title\">&nbsp;</div>\n";
print "<table cellspacing=\"0\">\n" .
"<tr><td>description</td><td>" . esc_html($descr) . "</td></tr>\n" .
"<tr><td>owner</td><td>$owner</td></tr>\n";
"<tr><td>owner</td><td>" . esc_html($owner) . "</td></tr>\n";
if (defined $cd{'rfc2822'}) {
print "<tr><td>last change</td><td>$cd{'rfc2822'}</td></tr>\n";
}

View File

@@ -860,7 +860,13 @@ sub READLINE {
if ($self->{i} >= scalar @{$self->{data}}) {
return undef;
}
return $self->{'data'}->[ $self->{i}++ ];
my $i = $self->{i};
if (wantarray) {
$self->{i} = $#{$self->{'data'}} + 1;
return splice(@{$self->{'data'}}, $i);
}
$self->{i} = $i + 1;
return $self->{'data'}->[ $i ];
}
sub CLOSE {

View File

@@ -29,5 +29,6 @@ WriteMakefile(
VERSION_FROM => 'Git.pm',
PM => \%pm,
MAKEFILE => 'perl.mak',
INSTALLSITEMAN3DIR => '$(SITEPREFIX)/share/man/man3',
%extra
);

View File

@@ -1277,6 +1277,9 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
compile_grep_patterns(revs->grep_filter);
}
if (revs->reverse && revs->reflog_info)
die("cannot combine --reverse with --walk-reflogs");
return left;
}

View File

@@ -1580,6 +1580,10 @@ static void *unpack_delta_entry(struct packed_git *p,
(uintmax_t)base_offset, p->pack_name);
delta_data = unpack_compressed_entry(p, w_curs, curpos, delta_size);
if (!delta_data)
die("failed to unpack compressed delta"
" at %"PRIuMAX" from %s",
(uintmax_t)curpos, p->pack_name);
result = patch_delta(base, base_size,
delta_data, delta_size,
sizep);

116
t/t0001-init.sh Executable file
View File

@@ -0,0 +1,116 @@
#!/bin/sh
test_description='git init'
. ./test-lib.sh
check_config () {
if test -d "$1" && test -f "$1/config" && test -d "$1/refs"
then
: happy
else
echo "expected a directory $1, a file $1/config and $1/refs"
return 1
fi
bare=$(GIT_CONFIG="$1/config" git config --bool core.bare)
worktree=$(GIT_CONFIG="$1/config" git config core.worktree) ||
worktree=unset
test "$bare" = "$2" && test "$worktree" = "$3" || {
echo "expected bare=$2 worktree=$3"
echo " got bare=$bare worktree=$worktree"
return 1
}
}
test_expect_success 'plain' '
(
unset GIT_DIR GIT_WORK_TREE &&
mkdir plain &&
cd plain &&
git init
) &&
check_config plain/.git false unset
'
test_expect_success 'plain with GIT_WORK_TREE' '
if (
unset GIT_DIR &&
mkdir plain-wt &&
cd plain-wt &&
GIT_WORK_TREE=$(pwd) git init
)
then
echo Should have failed -- GIT_WORK_TREE should not be used
false
fi
'
test_expect_success 'plain bare' '
(
unset GIT_DIR GIT_WORK_TREE GIT_CONFIG &&
mkdir plain-bare-1 &&
cd plain-bare-1 &&
git --bare init
) &&
check_config plain-bare-1 true unset
'
test_expect_success 'plain bare with GIT_WORK_TREE' '
if (
unset GIT_DIR GIT_CONFIG &&
mkdir plain-bare-2 &&
cd plain-bare-2 &&
GIT_WORK_TREE=$(pwd) git --bare init
)
then
echo Should have failed -- GIT_WORK_TREE should not be used
false
fi
'
test_expect_success 'GIT_DIR bare' '
(
unset GIT_CONFIG &&
mkdir git-dir-bare.git &&
GIT_DIR=git-dir-bare.git git init
) &&
check_config git-dir-bare.git true unset
'
test_expect_success 'GIT_DIR non-bare' '
(
unset GIT_CONFIG &&
mkdir non-bare &&
cd non-bare &&
GIT_DIR=.git git init
) &&
check_config non-bare/.git false unset
'
test_expect_success 'GIT_DIR & GIT_WORK_TREE (1)' '
(
unset GIT_CONFIG &&
mkdir git-dir-wt-1.git &&
GIT_WORK_TREE=$(pwd) GIT_DIR=git-dir-wt-1.git git init
) &&
check_config git-dir-wt-1.git false "$(pwd)"
'
test_expect_success 'GIT_DIR & GIT_WORK_TREE (2)' '
if (
unset GIT_CONFIG &&
mkdir git-dir-wt-2.git &&
GIT_WORK_TREE=$(pwd) GIT_DIR=git-dir-wt-2.git git --bare init
)
then
echo Should have failed -- --bare should not be used
false
fi
'
test_done

44
t/t0023-crlf-am.sh Executable file
View File

@@ -0,0 +1,44 @@
#!/bin/sh
test_description='Test am with auto.crlf'
. ./test-lib.sh
cat >patchfile <<\EOF
From 38be10072e45dd6b08ce40851e3fca60a31a340b Mon Sep 17 00:00:00 2001
From: Marius Storm-Olsen <x@y.com>
Date: Thu, 23 Aug 2007 13:00:00 +0200
Subject: test1
---
foo | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
create mode 100644 foo
diff --git a/foo b/foo
new file mode 100644
index 0000000000000000000000000000000000000000..5716ca5987cbf97d6bb54920bea6adde242d87e6
--- /dev/null
+++ b/foo
@@ -0,0 +1 @@
+bar
EOF
test_expect_success 'setup' '
git config core.autocrlf true &&
echo foo >bar &&
git add bar &&
test_tick &&
git commit -m initial
'
test_expect_success 'am' '
git am --binary -3 <patchfile &&
git diff-files --name-status --exit-code
'
test_done

52
t/t3050-subprojects-fetch.sh Executable file
View File

@@ -0,0 +1,52 @@
#!/bin/sh
test_description='fetching and pushing project with subproject'
. ./test-lib.sh
test_expect_success setup '
test_tick &&
mkdir -p sub && (
cd sub &&
git init &&
>subfile &&
git add subfile
git commit -m "subproject commit #1"
) &&
>mainfile
git add sub mainfile &&
test_tick &&
git commit -m "superproject commit #1"
'
test_expect_success clone '
git clone file://`pwd`/.git cloned &&
(git rev-parse HEAD; git ls-files -s) >expected &&
(
cd cloned &&
(git rev-parse HEAD; git ls-files -s) >../actual
) &&
diff -u expected actual
'
test_expect_success advance '
echo more >mainfile &&
git update-index --force-remove sub &&
mv sub/.git sub/.git-disabled &&
git add sub/subfile mainfile &&
mv sub/.git-disabled sub/.git &&
test_tick &&
git commit -m "superproject commit #2"
'
test_expect_success fetch '
(git rev-parse HEAD; git ls-files -s) >expected &&
(
cd cloned &&
git pull &&
(git rev-parse HEAD; git ls-files -s) >../actual
) &&
diff -u expected actual
'
test_done

View File

@@ -264,6 +264,27 @@ test_expect_success 'interrupted squash works as expected' '
test $one = $(git rev-parse HEAD~2)
'
test_expect_success 'interrupted squash works as expected (case 2)' '
for n in one two three four
do
echo $n >> conflict &&
git add conflict &&
git commit -m $n
done &&
one=$(git rev-parse HEAD~3) &&
! FAKE_LINES="3 squash 1 2" git rebase -i HEAD~3 &&
(echo one; echo four) > conflict &&
git add conflict &&
! git rebase --continue &&
(echo one; echo two; echo four) > conflict &&
git add conflict &&
! git rebase --continue &&
echo resolved > conflict &&
git add conflict &&
git rebase --continue &&
test $one = $(git rev-parse HEAD~2)
'
test_expect_success 'ignore patch if in upstream' '
HEAD=$(git rev-parse HEAD) &&
git checkout -b has-cherry-picked HEAD^ &&

77
t/t6028-merge-up-to-date.sh Executable file
View File

@@ -0,0 +1,77 @@
#!/bin/sh
test_description='merge fast forward and up to date'
. ./test-lib.sh
test_expect_success setup '
>file &&
git add file &&
test_tick &&
git commit -m initial &&
git tag c0 &&
echo second >file &&
git add file &&
test_tick &&
git commit -m second &&
git tag c1 &&
git branch test
'
test_expect_success 'merge -s recursive up-to-date' '
git reset --hard c1 &&
test_tick &&
git merge -s recursive c0 &&
expect=$(git rev-parse c1) &&
current=$(git rev-parse HEAD) &&
test "$expect" = "$current"
'
test_expect_success 'merge -s recursive fast-forward' '
git reset --hard c0 &&
test_tick &&
git merge -s recursive c1 &&
expect=$(git rev-parse c1) &&
current=$(git rev-parse HEAD) &&
test "$expect" = "$current"
'
test_expect_success 'merge -s ours up-to-date' '
git reset --hard c1 &&
test_tick &&
git merge -s ours c0 &&
expect=$(git rev-parse c1) &&
current=$(git rev-parse HEAD) &&
test "$expect" = "$current"
'
test_expect_success 'merge -s ours fast-forward' '
git reset --hard c0 &&
test_tick &&
git merge -s ours c1 &&
expect=$(git rev-parse c0^{tree}) &&
current=$(git rev-parse HEAD^{tree}) &&
test "$expect" = "$current"
'
test_expect_success 'merge -s subtree up-to-date' '
git reset --hard c1 &&
test_tick &&
git merge -s subtree c0 &&
expect=$(git rev-parse c1) &&
current=$(git rev-parse HEAD) &&
test "$expect" = "$current"
'
test_done

View File

@@ -170,6 +170,53 @@ test_expect_failure \
'git-fast-import <input'
rm -f .git/objects/pack_* .git/objects/index_*
cat >input <<INPUT_END
commit .badbranchname
committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
data <<COMMIT
corrupt
COMMIT
from refs/heads/master
INPUT_END
test_expect_failure \
'B: fail on invalid branch name ".badbranchname"' \
'git-fast-import <input'
rm -f .git/objects/pack_* .git/objects/index_*
cat >input <<INPUT_END
commit bad[branch]name
committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
data <<COMMIT
corrupt
COMMIT
from refs/heads/master
INPUT_END
test_expect_failure \
'B: fail on invalid branch name "bad[branch]name"' \
'git-fast-import <input'
rm -f .git/objects/pack_* .git/objects/index_*
cat >input <<INPUT_END
commit TEMP_TAG
committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
data <<COMMIT
tag base
COMMIT
from refs/heads/master
INPUT_END
test_expect_success \
'B: accept branch name "TEMP_TAG"' \
'git-fast-import <input &&
test -f .git/TEMP_TAG &&
test `git rev-parse master` = `git rev-parse TEMP_TAG^`'
rm -f .git/TEMP_TAG
###
### series C
###
@@ -731,4 +778,142 @@ test_expect_success \
'git-fast-import <input &&
test `git-rev-parse N2^{tree}` = `git-rev-parse N3^{tree}`'
###
### series O
###
cat >input <<INPUT_END
#we will
commit refs/heads/O1
# -- ignore all of this text
committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
# $GIT_COMMITTER_NAME has inserted here for his benefit.
data <<COMMIT
dirty directory copy
COMMIT
# don't forget the import blank line!
#
# yes, we started from our usual base of branch^0.
# i like branch^0.
from refs/heads/branch^0
# and we need to reuse file2/file5 from N3 above.
M 644 inline file2/file5
# otherwise the tree will be different
data <<EOF
$file5_data
EOF
# don't forget to copy file2 to file3
C file2 file3
#
# or to delete file5 from file2.
D file2/file5
# are we done yet?
INPUT_END
test_expect_success \
'O: comments are all skipped' \
'git-fast-import <input &&
test `git-rev-parse N3` = `git-rev-parse O1`'
cat >input <<INPUT_END
commit refs/heads/O2
committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
data <<COMMIT
dirty directory copy
COMMIT
from refs/heads/branch^0
M 644 inline file2/file5
data <<EOF
$file5_data
EOF
C file2 file3
D file2/file5
INPUT_END
test_expect_success \
'O: blank lines not necessary after data commands' \
'git-fast-import <input &&
test `git-rev-parse N3` = `git-rev-parse O2`'
test_expect_success \
'O: repack before next test' \
'git repack -a -d'
cat >input <<INPUT_END
commit refs/heads/O3
committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
data <<COMMIT
zstring
COMMIT
commit refs/heads/O3
committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
data <<COMMIT
zof
COMMIT
checkpoint
commit refs/heads/O3
mark :5
committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
data <<COMMIT
zempty
COMMIT
checkpoint
commit refs/heads/O3
committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
data <<COMMIT
zcommits
COMMIT
reset refs/tags/O3-2nd
from :5
INPUT_END
cat >expect <<INPUT_END
string
of
empty
commits
INPUT_END
test_expect_success \
'O: blank lines not necessary after other commands' \
'git-fast-import <input &&
test 8 = `find .git/objects/pack -type f | wc -l` &&
test `git rev-parse refs/tags/O3-2nd` = `git rev-parse O3^` &&
git log --reverse --pretty=oneline O3 | sed s/^.*z// >actual &&
git diff expect actual'
cat >input <<INPUT_END
commit refs/heads/O4
committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
data <<COMMIT
zstring
COMMIT
commit refs/heads/O4
committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
data <<COMMIT
zof
COMMIT
progress Two commits down, 2 to go!
commit refs/heads/O4
committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
data <<COMMIT
zempty
COMMIT
progress Three commits down, 1 to go!
commit refs/heads/O4
committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
data <<COMMIT
zcommits
COMMIT
progress I'm done!
INPUT_END
test_expect_success \
'O: progress outputs as requested by input' \
'git-fast-import <input >actual &&
grep "progress " <input >expect &&
git diff expect actual'
test_done