mirror of
https://github.com/git/git.git
synced 2026-04-01 20:40:08 +02:00
Merge branch 'master' of git://repo.or.cz/alt-git
This commit is contained in:
32
Documentation/RelNotes-1.6.4.2.txt
Normal file
32
Documentation/RelNotes-1.6.4.2.txt
Normal file
@@ -0,0 +1,32 @@
|
||||
GIT v1.6.4.2 Release Notes
|
||||
==========================
|
||||
|
||||
Fixes since v1.6.4.1
|
||||
--------------------
|
||||
|
||||
* --date=relative output between 1 and 5 years ago rounded the number of
|
||||
years when saying X years Y months ago, instead of rounding it down.
|
||||
|
||||
* "git add -p" did not handle changes in executable bits correctly
|
||||
(a regression around 1.6.3).
|
||||
|
||||
* "git apply" did not honor GNU diff's convention to mark the creation/deletion
|
||||
event with UNIX epoch timestamp on missing side.
|
||||
|
||||
* "git checkout" incorrectly removed files in a directory pointed by a
|
||||
symbolic link during a branch switch that replaces a directory with
|
||||
a symbolic link.
|
||||
|
||||
* "git clean -d -f" happily descended into a subdirectory that is managed by a
|
||||
separate git repository. It now requires two -f options for safety.
|
||||
|
||||
* "git fetch/push" over http transports had two rather grave bugs.
|
||||
|
||||
* "git format-patch --cover-letter" did not prepare the cover letter file
|
||||
for use with non-ASCII strings when there are the series contributors with
|
||||
non-ASCII names.
|
||||
|
||||
* "git pull origin branch" and "git fetch origin && git merge origin/branch"
|
||||
left different merge messages in the resulting commit.
|
||||
|
||||
Other minor documentation updates are included.
|
||||
@@ -1,8 +1,9 @@
|
||||
GIT v1.6.5 Release Notes
|
||||
========================
|
||||
|
||||
In git 1.7.0, which is planned to be the release after 1.6.5, "git push"
|
||||
into a branch that is currently checked out will be refused by default.
|
||||
In git 1.7.0, which was planned to be the release after 1.6.5, "git
|
||||
push" into a branch that is currently checked out will be refused by
|
||||
default.
|
||||
|
||||
You can choose what should happen upon such a push by setting the
|
||||
configuration variable receive.denyCurrentBranch in the receiving
|
||||
@@ -31,14 +32,88 @@ Updates since v1.6.4
|
||||
|
||||
(subsystems)
|
||||
|
||||
* various updates to git-svn and gitweb.
|
||||
|
||||
(portability)
|
||||
|
||||
* more improvements on mingw port.
|
||||
|
||||
(performance)
|
||||
|
||||
* On major platforms, the system can be compiled to use with Linus's
|
||||
block-sha1 implementation of the SHA-1 hash algorithm, which
|
||||
outperforms the default fallback implementation we borrowed from
|
||||
Mozzilla.
|
||||
|
||||
* Unnecessary inefficiency in deepening of a shallow repository has
|
||||
been removed.
|
||||
|
||||
(usability, bells and whistles)
|
||||
|
||||
* Human writable date format to various options, e.g. --since=yesterday,
|
||||
master@{2000.09.17}, are taught to infer some omitted input properly.
|
||||
|
||||
* refs/replace/ hierarchy is designed to be usable as a replacement
|
||||
of the "grafts" mechanism, with the added advantage that it can be
|
||||
transferred across repositories.
|
||||
|
||||
* "git am" learned to optionally ignore whitespace differences.
|
||||
|
||||
* "git am" handles input e-mail files that has CRLF line endings sensibly.
|
||||
|
||||
* "git am" learned "--scissors" option to allow you to discard early part
|
||||
of an incoming e-mail.
|
||||
|
||||
* "git checkout", "git reset" and "git stash" learned to pick and
|
||||
choose to use selected changes you made, similar to "git add -p".
|
||||
|
||||
* "git clone" learned a "-b" option to pick a HEAD to check out
|
||||
different from the remote's default branch.
|
||||
|
||||
* "git commit --dry-run $args" is a new recommended way to ask "what would
|
||||
happen if I try to commit with these arguments."
|
||||
|
||||
* "git commit --dry-run" and "git status" shows conflicted paths in a
|
||||
separate section to make them easier to spot during a merge.
|
||||
|
||||
* "git cvsimport" now supports password-protected pserver access even
|
||||
when the password is not taken from ~/.cvspass file.
|
||||
|
||||
* "git fast-export" learned --no-data option that can be useful when
|
||||
reordering commits and trees without touching the contents of
|
||||
blobs.
|
||||
|
||||
* "git init" learned to mkdir/chdir into a directory when given an
|
||||
extra argument (i.e. "git init this").
|
||||
|
||||
* "git instaweb" optionally can use mongoose as the web server.
|
||||
|
||||
* "git log --decorate" can optionally be told with --decorate=full to
|
||||
give the reference name in full.
|
||||
|
||||
* "git push" can be told to be --quiet.
|
||||
|
||||
* informational output from "git reset" that lists the locally modified
|
||||
paths is made consistent with that of "git checkout $another_branch".
|
||||
|
||||
* "git submodule" learned to give submodule name to scripts run with
|
||||
"foreach" subcommand.
|
||||
|
||||
* various subcommands to "git submodule" learned --recursive option.
|
||||
|
||||
* "git submodule summary" learned --files option to compare the work
|
||||
tree vs the commit bound at submodule path, instead of comparing
|
||||
the index.
|
||||
|
||||
* "git upload-pack", which is the server side support for "git clone" and
|
||||
"git fetch", can call a new post-upload-pack hook for statistics purposes.
|
||||
|
||||
(developers)
|
||||
|
||||
* With GIT_TEST_OPTS="--root=/p/a/t/h", tests can be run outside the
|
||||
source directory; using tmpfs may give faster turnaround.
|
||||
|
||||
|
||||
Fixes since v1.6.4
|
||||
------------------
|
||||
|
||||
@@ -48,4 +123,8 @@ Fixes since v1.6.4
|
||||
# Here are fixes that this release has, but have not been backported to
|
||||
# v1.6.4.X series.
|
||||
|
||||
|
||||
--
|
||||
exec >/var/tmp/1
|
||||
O=v1.6.4.2-298-gdf01e7c
|
||||
echo O=$(git describe master)
|
||||
git shortlog --no-merges $O..master --not maint
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
ifndef::git-pull[]
|
||||
-q::
|
||||
--quiet::
|
||||
Pass --quiet to git-fetch-pack and silence any other internally
|
||||
@@ -6,6 +7,7 @@
|
||||
-v::
|
||||
--verbose::
|
||||
Be verbose.
|
||||
endif::git-pull[]
|
||||
|
||||
-a::
|
||||
--append::
|
||||
|
||||
@@ -13,7 +13,7 @@ SYNOPSIS
|
||||
[--3way] [--interactive] [--committer-date-is-author-date]
|
||||
[--ignore-date] [--ignore-space-change | --ignore-whitespace]
|
||||
[--whitespace=<option>] [-C<n>] [-p<n>] [--directory=<dir>]
|
||||
[--reject] [-q | --quiet]
|
||||
[--reject] [-q | --quiet] [--scissors]
|
||||
[<mbox> | <Maildir>...]
|
||||
'git am' (--skip | --resolved | --abort)
|
||||
|
||||
@@ -39,6 +39,11 @@ OPTIONS
|
||||
--keep::
|
||||
Pass `-k` flag to 'git-mailinfo' (see linkgit:git-mailinfo[1]).
|
||||
|
||||
-c::
|
||||
--scissors::
|
||||
Remove everything in body before a scissors line (see
|
||||
linkgit:git-mailinfo[1]).
|
||||
|
||||
-q::
|
||||
--quiet::
|
||||
Be quiet. Only print error messages.
|
||||
@@ -128,10 +133,8 @@ the commit, after stripping common prefix "[PATCH <anything>]".
|
||||
The "Subject: " line is supposed to concisely describe what the
|
||||
commit is about in one line of text.
|
||||
|
||||
"From: " and "Subject: " lines starting the body (the rest of the
|
||||
message after the blank line terminating the RFC2822 headers)
|
||||
override the respective commit author name and title values taken
|
||||
from the headers.
|
||||
"From: " and "Subject: " lines starting the body override the respective
|
||||
commit author name and title values taken from the headers.
|
||||
|
||||
The commit message is formed by the title taken from the
|
||||
"Subject: ", a blank line and the body of the message up to
|
||||
|
||||
@@ -9,7 +9,7 @@ git-archive - Create an archive of files from a named tree
|
||||
SYNOPSIS
|
||||
--------
|
||||
[verse]
|
||||
'git archive' --format=<fmt> [--list] [--prefix=<prefix>/] [<extra>]
|
||||
'git archive' [--format=<fmt>] [--list] [--prefix=<prefix>/] [<extra>]
|
||||
[--output=<file>] [--worktree-attributes]
|
||||
[--remote=<repo> [--exec=<git-upload-archive>]] <tree-ish>
|
||||
[path...]
|
||||
|
||||
@@ -76,6 +76,7 @@ OPTIONS
|
||||
based sha1 expressions such as "<branchname>@\{yesterday}".
|
||||
|
||||
-f::
|
||||
--force::
|
||||
Reset <branchname> to <startpoint> if <branchname> exists
|
||||
already. Without `-f` 'git-branch' refuses to change an existing branch.
|
||||
|
||||
@@ -209,6 +210,12 @@ but different purposes:
|
||||
- `--no-merged` is used to find branches which are candidates for merging
|
||||
into HEAD, since those branches are not fully contained by HEAD.
|
||||
|
||||
SEE ALSO
|
||||
--------
|
||||
linkgit:git-check-ref-format[1],
|
||||
linkgit:git-fetch[1],
|
||||
linkgit:git-remote[1].
|
||||
|
||||
Author
|
||||
------
|
||||
Written by Linus Torvalds <torvalds@osdl.org> and Junio C Hamano <gitster@pobox.com>
|
||||
|
||||
@@ -11,6 +11,7 @@ SYNOPSIS
|
||||
'git checkout' [-q] [-f] [-m] [<branch>]
|
||||
'git checkout' [-q] [-f] [-m] [-b <new_branch>] [<start_point>]
|
||||
'git checkout' [-f|--ours|--theirs|-m|--conflict=<style>] [<tree-ish>] [--] <paths>...
|
||||
'git checkout' --patch [<tree-ish>] [--] [<paths>...]
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
@@ -25,7 +26,7 @@ use the --track or --no-track options, which will be passed to `git
|
||||
branch`. As a convenience, --track without `-b` implies branch
|
||||
creation; see the description of --track below.
|
||||
|
||||
When <paths> are given, this command does *not* switch
|
||||
When <paths> or --patch are given, this command does *not* switch
|
||||
branches. It updates the named paths in the working tree from
|
||||
the index file, or from a named <tree-ish> (most often a commit). In
|
||||
this case, the `-b` and `--track` options are meaningless and giving
|
||||
@@ -45,9 +46,11 @@ file can be discarded to recreate the original conflicted merge result.
|
||||
OPTIONS
|
||||
-------
|
||||
-q::
|
||||
--quiet::
|
||||
Quiet, suppress feedback messages.
|
||||
|
||||
-f::
|
||||
--force::
|
||||
When switching branches, proceed even if the index or the
|
||||
working tree differs from HEAD. This is used to throw away
|
||||
local changes.
|
||||
@@ -113,6 +116,16 @@ the conflicted merge in the specified paths.
|
||||
"merge" (default) and "diff3" (in addition to what is shown by
|
||||
"merge" style, shows the original contents).
|
||||
|
||||
-p::
|
||||
--patch::
|
||||
Interactively select hunks in the difference between the
|
||||
<tree-ish> (or the index, if unspecified) and the working
|
||||
tree. The chosen hunks are then applied in reverse to the
|
||||
working tree (and if a <tree-ish> was specified, the index).
|
||||
+
|
||||
This means that you can use `git checkout -p` to selectively discard
|
||||
edits from your current working tree.
|
||||
|
||||
<branch>::
|
||||
Branch to checkout; if it refers to a branch (i.e., a name that,
|
||||
when prepended with "refs/heads/", is a valid ref), then that
|
||||
|
||||
@@ -32,6 +32,7 @@ OPTIONS
|
||||
if you really want to remove such a directory.
|
||||
|
||||
-f::
|
||||
--force::
|
||||
If the git configuration specifies clean.requireForce as true,
|
||||
'git-clean' will refuse to run unless given -f or -n.
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ SYNOPSIS
|
||||
'git clone' [--template=<template_directory>]
|
||||
[-l] [-s] [--no-hardlinks] [-q] [-n] [--bare] [--mirror]
|
||||
[-o <name>] [-u <upload-pack>] [--reference <repository>]
|
||||
[--depth <depth>] [--] <repository> [<directory>]
|
||||
[--depth <depth>] [--recursive] [--] <repository> [<directory>]
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
@@ -84,7 +84,7 @@ its source repository, you can simply run `git repack -a` to copy all
|
||||
objects from the source repository into a pack in the cloned repository.
|
||||
|
||||
--reference <repository>::
|
||||
If the reference repository is on the local machine
|
||||
If the reference repository is on the local machine,
|
||||
automatically setup .git/objects/info/alternates to
|
||||
obtain objects from the reference repository. Using
|
||||
an already existing repository as an alternate will
|
||||
@@ -127,6 +127,13 @@ objects from the source repository into a pack in the cloned repository.
|
||||
Instead of using the remote name 'origin' to keep track
|
||||
of the upstream repository, use <name>.
|
||||
|
||||
--branch <name>::
|
||||
-b <name>::
|
||||
Instead of pointing the newly created HEAD to the branch pointed
|
||||
to by the cloned repositoroy's HEAD, point to <name> branch
|
||||
instead. In a non-bare repository, this is the branch that will
|
||||
be checked out.
|
||||
|
||||
--upload-pack <upload-pack>::
|
||||
-u <upload-pack>::
|
||||
When given, and the repository to clone from is accessed
|
||||
@@ -147,6 +154,14 @@ objects from the source repository into a pack in the cloned repository.
|
||||
with a long history, and would want to send in fixes
|
||||
as patches.
|
||||
|
||||
--recursive::
|
||||
After the clone is created, initialize all submodules within,
|
||||
using their default settings. This is equivalent to running
|
||||
'git submodule update --init --recursive' immediately after
|
||||
the clone is finished. This option is ignored if the cloned
|
||||
repository does not have a worktree/checkout (i.e. if any of
|
||||
`--no-checkout`/`-n`, `--bare`, or `--mirror` is given)
|
||||
|
||||
<repository>::
|
||||
The (possibly remote) repository to clone from. See the
|
||||
<<URLS,URLS>> section below for more information on specifying
|
||||
|
||||
@@ -8,8 +8,8 @@ git-commit - Record changes to the repository
|
||||
SYNOPSIS
|
||||
--------
|
||||
[verse]
|
||||
'git commit' [-a | --interactive] [-s] [-v] [-u<mode>] [--amend]
|
||||
[(-c | -C) <commit>] [-F <file> | -m <msg>]
|
||||
'git commit' [-a | --interactive] [-s] [-v] [-u<mode>] [--amend] [--dry-run]
|
||||
[(-c | -C) <commit>] [-F <file> | -m <msg>] [--dry-run]
|
||||
[--allow-empty] [--no-verify] [-e] [--author=<author>]
|
||||
[--cleanup=<mode>] [--] [[-i | -o ]<file>...]
|
||||
|
||||
@@ -42,10 +42,9 @@ The content to be added can be specified in several ways:
|
||||
by one which files should be part of the commit, before finalizing the
|
||||
operation. Currently, this is done by invoking 'git-add --interactive'.
|
||||
|
||||
The 'git-status' command can be used to obtain a
|
||||
The `--dry-run` option can be used to obtain a
|
||||
summary of what is included by any of the above for the next
|
||||
commit by giving the same set of parameters you would give to
|
||||
this command.
|
||||
commit by giving the same set of parameters (options and paths).
|
||||
|
||||
If you make a commit and then find a mistake immediately after
|
||||
that, you can recover from it with 'git-reset'.
|
||||
@@ -70,6 +69,12 @@ OPTIONS
|
||||
Like '-C', but with '-c' the editor is invoked, so that
|
||||
the user can further edit the commit message.
|
||||
|
||||
--dry-run::
|
||||
Do not actually make a commit, but show the list of paths
|
||||
with updates in the index, paths with changes in the work tree,
|
||||
and paths that are untracked, similar to the one that is given
|
||||
in the commit log editor.
|
||||
|
||||
-F <file>::
|
||||
--file=<file>::
|
||||
Take the commit message from the given file. Use '-' to
|
||||
@@ -198,6 +203,11 @@ specified.
|
||||
--quiet::
|
||||
Suppress commit summary message.
|
||||
|
||||
--dry-run::
|
||||
Do not create a commit, but show a list of paths that are
|
||||
to be committed, paths with local changes that will be left
|
||||
uncommitted and paths that are untracked.
|
||||
|
||||
\--::
|
||||
Do not interpret any more arguments as options.
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ automatic consolidation of packs.
|
||||
|
||||
--prune=<date>::
|
||||
Prune loose objects older than date (default is 2 weeks ago,
|
||||
overrideable by the config variable `gc.pruneExpire`). This
|
||||
overridable by the config variable `gc.pruneExpire`). This
|
||||
option is on by default.
|
||||
|
||||
--no-prune::
|
||||
|
||||
@@ -29,7 +29,7 @@ OPTIONS
|
||||
The HTTP daemon command-line that will be executed.
|
||||
Command-line options may be specified here, and the
|
||||
configuration file will be added at the end of the command-line.
|
||||
Currently lighttpd, apache2 and webrick are supported.
|
||||
Currently apache2, lighttpd, mongoose and webrick are supported.
|
||||
(Default: lighttpd)
|
||||
|
||||
-m::
|
||||
|
||||
@@ -37,8 +37,12 @@ include::diff-options.txt[]
|
||||
and <until>, see "SPECIFYING REVISIONS" section in
|
||||
linkgit:git-rev-parse[1].
|
||||
|
||||
--decorate::
|
||||
Print out the ref names of any commits that are shown.
|
||||
--decorate[=short|full]::
|
||||
Print out the ref names of any commits that are shown. If 'short' is
|
||||
specified, the ref name prefixes 'refs/heads/', 'refs/tags/' and
|
||||
'refs/remotes/' will not be printed. If 'full' is specified, the
|
||||
full ref name (including prefix) will be printed. The default option
|
||||
is 'short'.
|
||||
|
||||
--source::
|
||||
Print out the ref name given on the command line by which each
|
||||
|
||||
@@ -8,7 +8,7 @@ git-mailinfo - Extracts patch and authorship from a single e-mail message
|
||||
|
||||
SYNOPSIS
|
||||
--------
|
||||
'git mailinfo' [-k] [-u | --encoding=<encoding> | -n] <msg> <patch>
|
||||
'git mailinfo' [-k] [-u | --encoding=<encoding> | -n] [--scissors] <msg> <patch>
|
||||
|
||||
|
||||
DESCRIPTION
|
||||
@@ -49,6 +49,20 @@ conversion, even with this flag.
|
||||
-n::
|
||||
Disable all charset re-coding of the metadata.
|
||||
|
||||
--scissors::
|
||||
Remove everything in body before a scissors line. A line that
|
||||
mainly consists of scissors (either ">8" or "8<") and perforation
|
||||
(dash "-") marks is called a scissors line, and is used to request
|
||||
the reader to cut the message at that line. If such a line
|
||||
appears in the body of the message before the patch, everything
|
||||
before it (including the scissors line itself) is ignored when
|
||||
this option is used.
|
||||
+
|
||||
This is useful if you want to begin your message in a discussion thread
|
||||
with comments and suggestions on the message you are responding to, and to
|
||||
conclude it with a patch submission, separating the discussion and the
|
||||
beginning of the proposed commit log message with a scissors line.
|
||||
|
||||
<msg>::
|
||||
The commit log message extracted from e-mail, usually
|
||||
except the title line which comes from e-mail Subject.
|
||||
|
||||
@@ -28,6 +28,7 @@ committed.
|
||||
OPTIONS
|
||||
-------
|
||||
-f::
|
||||
--force::
|
||||
Force renaming or moving of a file even if the target exists
|
||||
-k::
|
||||
Skip move or rename actions which would lead to an error
|
||||
|
||||
@@ -10,6 +10,7 @@ SYNOPSIS
|
||||
[verse]
|
||||
'git reset' [--mixed | --soft | --hard | --merge] [-q] [<commit>]
|
||||
'git reset' [-q] [<commit>] [--] <paths>...
|
||||
'git reset' --patch [<commit>] [--] [<paths>...]
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
@@ -23,8 +24,9 @@ the undo in the history.
|
||||
If you want to undo a commit other than the latest on a branch,
|
||||
linkgit:git-revert[1] is your friend.
|
||||
|
||||
The second form with 'paths' is used to revert selected paths in
|
||||
the index from a given commit, without moving HEAD.
|
||||
The second and third forms with 'paths' and/or --patch are used to
|
||||
revert selected paths in the index from a given commit, without moving
|
||||
HEAD.
|
||||
|
||||
|
||||
OPTIONS
|
||||
@@ -50,6 +52,15 @@ OPTIONS
|
||||
and updates the files that are different between the named commit
|
||||
and the current commit in the working tree.
|
||||
|
||||
-p::
|
||||
--patch::
|
||||
Interactively select hunks in the difference between the index
|
||||
and <commit> (defaults to HEAD). The chosen hunks are applied
|
||||
in reverse to the index.
|
||||
+
|
||||
This means that `git reset -p` is the opposite of `git add -p` (see
|
||||
linkgit:git-add[1]).
|
||||
|
||||
-q::
|
||||
Be quiet, only report errors.
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ SYNOPSIS
|
||||
'git stash' drop [-q|--quiet] [<stash>]
|
||||
'git stash' ( pop | apply ) [--index] [-q|--quiet] [<stash>]
|
||||
'git stash' branch <branchname> [<stash>]
|
||||
'git stash' [save [--keep-index] [-q|--quiet] [<message>]]
|
||||
'git stash' [save [--patch] [-k|--[no-]keep-index] [-q|--quiet] [<message>]]
|
||||
'git stash' clear
|
||||
'git stash' create
|
||||
|
||||
@@ -42,15 +42,27 @@ is also possible).
|
||||
OPTIONS
|
||||
-------
|
||||
|
||||
save [--keep-index] [-q|--quiet] [<message>]::
|
||||
save [--patch] [--[no-]keep-index] [-q|--quiet] [<message>]::
|
||||
|
||||
Save your local modifications to a new 'stash', and run `git reset
|
||||
--hard` to revert them. This is the default action when no
|
||||
subcommand is given. The <message> part is optional and gives
|
||||
the description along with the stashed state.
|
||||
--hard` to revert them. The <message> part is optional and gives
|
||||
the description along with the stashed state. For quickly making
|
||||
a snapshot, you can omit _both_ "save" and <message>, but giving
|
||||
only <message> does not trigger this action to prevent a misspelled
|
||||
subcommand from making an unwanted stash.
|
||||
+
|
||||
If the `--keep-index` option is used, all changes already added to the
|
||||
index are left intact.
|
||||
+
|
||||
With `--patch`, you can interactively select hunks from in the diff
|
||||
between HEAD and the working tree to be stashed. The stash entry is
|
||||
constructed such that its index state is the same as the index state
|
||||
of your repository, and its worktree contains only the changes you
|
||||
selected interactively. The selected changes are then rolled back
|
||||
from your worktree.
|
||||
+
|
||||
The `--patch` option implies `--keep-index`. You can use
|
||||
`--no-keep-index` to override this.
|
||||
|
||||
list [<options>]::
|
||||
|
||||
|
||||
@@ -11,12 +11,12 @@ SYNOPSIS
|
||||
[verse]
|
||||
'git submodule' [--quiet] add [-b branch]
|
||||
[--reference <repository>] [--] <repository> <path>
|
||||
'git submodule' [--quiet] status [--cached] [--] [<path>...]
|
||||
'git submodule' [--quiet] status [--cached] [--recursive] [--] [<path>...]
|
||||
'git submodule' [--quiet] init [--] [<path>...]
|
||||
'git submodule' [--quiet] update [--init] [-N|--no-fetch] [--rebase]
|
||||
[--reference <repository>] [--merge] [--] [<path>...]
|
||||
'git submodule' [--quiet] summary [--cached] [--summary-limit <n>] [commit] [--] [<path>...]
|
||||
'git submodule' [--quiet] foreach <command>
|
||||
[--reference <repository>] [--merge] [--recursive] [--] [<path>...]
|
||||
'git submodule' [--quiet] summary [--cached|--files] [--summary-limit <n>] [commit] [--] [<path>...]
|
||||
'git submodule' [--quiet] foreach [--recursive] <command>
|
||||
'git submodule' [--quiet] sync [--] [<path>...]
|
||||
|
||||
|
||||
@@ -100,6 +100,9 @@ status::
|
||||
initialized and `+` if the currently checked out submodule commit
|
||||
does not match the SHA-1 found in the index of the containing
|
||||
repository. This command is the default command for 'git-submodule'.
|
||||
+
|
||||
If '--recursive' is specified, this command will recurse into nested
|
||||
submodules, and show their status as well.
|
||||
|
||||
init::
|
||||
Initialize the submodules, i.e. register each submodule name
|
||||
@@ -122,21 +125,31 @@ update::
|
||||
If the submodule is not yet initialized, and you just want to use the
|
||||
setting as stored in .gitmodules, you can automatically initialize the
|
||||
submodule with the --init option.
|
||||
+
|
||||
If '--recursive' is specified, this command will recurse into the
|
||||
registered submodules, and update any nested submodules within.
|
||||
|
||||
summary::
|
||||
Show commit summary between the given commit (defaults to HEAD) and
|
||||
working tree/index. For a submodule in question, a series of commits
|
||||
in the submodule between the given super project commit and the
|
||||
index or working tree (switched by --cached) are shown.
|
||||
index or working tree (switched by --cached) are shown. If the option
|
||||
--files is given, show the series of commits in the submodule between
|
||||
the index of the super project and the working tree of the submodule
|
||||
(this option doesn't allow to use the --cached option or to provide an
|
||||
explicit commit).
|
||||
|
||||
foreach::
|
||||
Evaluates an arbitrary shell command in each checked out submodule.
|
||||
The command has access to the variables $path and $sha1:
|
||||
The command has access to the variables $name, $path and $sha1:
|
||||
$name is the name of the relevant submodule section in .gitmodules,
|
||||
$path is the name of the submodule directory relative to the
|
||||
superproject, and $sha1 is the commit as recorded in the superproject.
|
||||
Any submodules defined in the superproject but not checked out are
|
||||
ignored by this command. Unless given --quiet, foreach prints the name
|
||||
of each submodule before evaluating the command.
|
||||
If --recursive is given, submodules are traversed recursively (i.e.
|
||||
the given shell command is evaluated in nested submodules as well).
|
||||
A non-zero return from the command in any submodule causes
|
||||
the processing to terminate. This can be overridden by adding '|| :'
|
||||
to the end of the command.
|
||||
@@ -169,6 +182,11 @@ OPTIONS
|
||||
commands typically use the commit found in the submodule HEAD, but
|
||||
with this option, the commit stored in the index is used instead.
|
||||
|
||||
--files::
|
||||
This option is only valid for the summary command. This command
|
||||
compares the commit in the index with that in the submodule HEAD
|
||||
when this option is used.
|
||||
|
||||
-n::
|
||||
--summary-limit::
|
||||
This option is only valid for the summary command.
|
||||
@@ -209,6 +227,12 @@ OPTIONS
|
||||
*NOTE*: Do *not* use this option unless you have read the note
|
||||
for linkgit:git-clone[1]'s --reference and --shared options carefully.
|
||||
|
||||
--recursive::
|
||||
This option is only valid for foreach, update and status commands.
|
||||
Traverse submodules recursively. The operation is performed not
|
||||
only in the submodules of the current repo, but also
|
||||
in any nested submodules inside those submodules (and so on).
|
||||
|
||||
<path>...::
|
||||
Paths to submodule(s). When specified this will restrict the command
|
||||
to only operate on the submodules found at the specified paths.
|
||||
|
||||
@@ -10,17 +10,15 @@ SYNOPSIS
|
||||
--------
|
||||
[verse]
|
||||
'git tag' [-a | -s | -u <key-id>] [-f] [-m <msg> | -F <file>]
|
||||
<name> [<commit> | <object>]
|
||||
'git tag' -d <name>...
|
||||
<tagname> [<commit> | <object>]
|
||||
'git tag' -d <tagname>...
|
||||
'git tag' [-n[<num>]] -l [--contains <commit>] [<pattern>]
|
||||
'git tag' -v <name>...
|
||||
'git tag' -v <tagname>...
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
|
||||
Adds a 'tag' reference in `.git/refs/tags/`. The tag <name> must pass
|
||||
linkgit:git-check-ref-format[1] which basicly means that control characters,
|
||||
space, ~, ^, :, ?, *, [ and \ are prohibited.
|
||||
Adds a tag reference in `.git/refs/tags/`.
|
||||
|
||||
Unless `-f` is given, the tag must not yet exist in
|
||||
`.git/refs/tags/` directory.
|
||||
@@ -53,6 +51,7 @@ OPTIONS
|
||||
Make a GPG-signed tag, using the given key
|
||||
|
||||
-f::
|
||||
--force::
|
||||
Replace an existing tag with the given name (instead of failing)
|
||||
|
||||
-d::
|
||||
@@ -88,6 +87,12 @@ OPTIONS
|
||||
Implies `-a` if none of `-a`, `-s`, or `-u <key-id>`
|
||||
is given.
|
||||
|
||||
<tagname>::
|
||||
The name of the tag to create, delete, or describe.
|
||||
The new tag name must pass all checks defined by
|
||||
linkgit:git-check-ref-format[1]. Some of these checks
|
||||
may restrict the characters allowed in a tag name.
|
||||
|
||||
CONFIGURATION
|
||||
-------------
|
||||
By default, 'git-tag' in sign-with-default mode (-s) will use your
|
||||
@@ -252,6 +257,10 @@ $ GIT_COMMITTER_DATE="2006-10-02 10:31" git tag -s v1.0.1
|
||||
------------
|
||||
|
||||
|
||||
SEE ALSO
|
||||
--------
|
||||
linkgit:git-check-ref-format[1].
|
||||
|
||||
Author
|
||||
------
|
||||
Written by Linus Torvalds <torvalds@osdl.org>,
|
||||
|
||||
@@ -20,6 +20,8 @@ The UI for the protocol is on the 'git-fetch-pack' side, and the
|
||||
program pair is meant to be used to pull updates from a remote
|
||||
repository. For push operations, see 'git-send-pack'.
|
||||
|
||||
After finishing the operation successfully, `post-upload-pack`
|
||||
hook is called (see linkgit:githooks[5]).
|
||||
|
||||
OPTIONS
|
||||
-------
|
||||
|
||||
@@ -12,7 +12,8 @@ SYNOPSIS
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
Creates a tree object using the current index.
|
||||
Creates a tree object using the current index. The name of the new
|
||||
tree object is printed to standard output.
|
||||
|
||||
The index must be in a fully merged state.
|
||||
|
||||
|
||||
@@ -43,9 +43,10 @@ unreleased) version of git, that is available from 'master'
|
||||
branch of the `git.git` repository.
|
||||
Documentation for older releases are available here:
|
||||
|
||||
* link:v1.6.4.1/git.html[documentation for release 1.6.4.1]
|
||||
* link:v1.6.4.2/git.html[documentation for release 1.6.4.2]
|
||||
|
||||
* release notes for
|
||||
link:RelNotes-1.6.4.2.txt[1.6.4.2],
|
||||
link:RelNotes-1.6.4.1.txt[1.6.4.1],
|
||||
link:RelNotes-1.6.4.txt[1.6.4].
|
||||
|
||||
|
||||
@@ -26,8 +26,11 @@ executable by default.
|
||||
|
||||
This document describes the currently defined hooks.
|
||||
|
||||
HOOKS
|
||||
-----
|
||||
|
||||
applypatch-msg
|
||||
--------------
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
This hook is invoked by 'git-am' script. It takes a single
|
||||
parameter, the name of the file that holds the proposed commit
|
||||
@@ -43,7 +46,7 @@ The default 'applypatch-msg' hook, when enabled, runs the
|
||||
'commit-msg' hook, if the latter is enabled.
|
||||
|
||||
pre-applypatch
|
||||
--------------
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
This hook is invoked by 'git-am'. It takes no parameter, and is
|
||||
invoked after the patch is applied, but before a commit is made.
|
||||
@@ -58,7 +61,7 @@ The default 'pre-applypatch' hook, when enabled, runs the
|
||||
'pre-commit' hook, if the latter is enabled.
|
||||
|
||||
post-applypatch
|
||||
---------------
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
This hook is invoked by 'git-am'. It takes no parameter,
|
||||
and is invoked after the patch is applied and a commit is made.
|
||||
@@ -67,7 +70,7 @@ This hook is meant primarily for notification, and cannot affect
|
||||
the outcome of 'git-am'.
|
||||
|
||||
pre-commit
|
||||
----------
|
||||
~~~~~~~~~~
|
||||
|
||||
This hook is invoked by 'git-commit', and can be bypassed
|
||||
with `\--no-verify` option. It takes no parameter, and is
|
||||
@@ -84,7 +87,7 @@ variable `GIT_EDITOR=:` if the command will not bring up an editor
|
||||
to modify the commit message.
|
||||
|
||||
prepare-commit-msg
|
||||
------------------
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
This hook is invoked by 'git-commit' right after preparing the
|
||||
default log message, and before the editor is started.
|
||||
@@ -109,7 +112,7 @@ The sample `prepare-commit-msg` hook that comes with git comments
|
||||
out the `Conflicts:` part of a merge's commit message.
|
||||
|
||||
commit-msg
|
||||
----------
|
||||
~~~~~~~~~~
|
||||
|
||||
This hook is invoked by 'git-commit', and can be bypassed
|
||||
with `\--no-verify` option. It takes a single parameter, the
|
||||
@@ -126,7 +129,7 @@ The default 'commit-msg' hook, when enabled, detects duplicate
|
||||
"Signed-off-by" lines, and aborts the commit if one is found.
|
||||
|
||||
post-commit
|
||||
-----------
|
||||
~~~~~~~~~~~
|
||||
|
||||
This hook is invoked by 'git-commit'. It takes no
|
||||
parameter, and is invoked after a commit is made.
|
||||
@@ -135,14 +138,14 @@ This hook is meant primarily for notification, and cannot affect
|
||||
the outcome of 'git-commit'.
|
||||
|
||||
pre-rebase
|
||||
----------
|
||||
~~~~~~~~~~
|
||||
|
||||
This hook is called by 'git-rebase' and can be used to prevent a branch
|
||||
from getting rebased.
|
||||
|
||||
|
||||
post-checkout
|
||||
-----------
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
This hook is invoked when a 'git-checkout' is run after having updated the
|
||||
worktree. The hook is given three parameters: the ref of the previous HEAD,
|
||||
@@ -160,7 +163,7 @@ differences from the previous HEAD if different, or set working dir metadata
|
||||
properties.
|
||||
|
||||
post-merge
|
||||
-----------
|
||||
~~~~~~~~~~
|
||||
|
||||
This hook is invoked by 'git-merge', which happens when a 'git-pull'
|
||||
is done on a local repository. The hook takes a single parameter, a status
|
||||
@@ -175,7 +178,7 @@ for an example of how to do this.
|
||||
|
||||
[[pre-receive]]
|
||||
pre-receive
|
||||
-----------
|
||||
~~~~~~~~~~~
|
||||
|
||||
This hook is invoked by 'git-receive-pack' on the remote repository,
|
||||
which happens when a 'git-push' is done on a local repository.
|
||||
@@ -204,7 +207,7 @@ for the user.
|
||||
|
||||
[[update]]
|
||||
update
|
||||
------
|
||||
~~~~~~
|
||||
|
||||
This hook is invoked by 'git-receive-pack' on the remote repository,
|
||||
which happens when a 'git-push' is done on a local repository.
|
||||
@@ -247,7 +250,7 @@ unannotated tags to be pushed.
|
||||
|
||||
[[post-receive]]
|
||||
post-receive
|
||||
------------
|
||||
~~~~~~~~~~~~
|
||||
|
||||
This hook is invoked by 'git-receive-pack' on the remote repository,
|
||||
which happens when a 'git-push' is done on a local repository.
|
||||
@@ -277,7 +280,7 @@ emails.
|
||||
|
||||
[[post-update]]
|
||||
post-update
|
||||
-----------
|
||||
~~~~~~~~~~~
|
||||
|
||||
This hook is invoked by 'git-receive-pack' on the remote repository,
|
||||
which happens when a 'git-push' is done on a local repository.
|
||||
@@ -307,8 +310,37 @@ Both standard output and standard error output are forwarded to
|
||||
'git-send-pack' on the other end, so you can simply `echo` messages
|
||||
for the user.
|
||||
|
||||
post-upload-pack
|
||||
----------------
|
||||
|
||||
After upload-pack successfully finishes its operation, this hook is called
|
||||
for logging purposes.
|
||||
|
||||
The hook is passed various pieces of information, one per line, from its
|
||||
standard input. Currently the following items can be fed to the hook, but
|
||||
more types of information may be added in the future:
|
||||
|
||||
want SHA-1::
|
||||
40-byte hexadecimal object name the client asked to include in the
|
||||
resulting pack. Can occur one or more times in the input.
|
||||
|
||||
have SHA-1::
|
||||
40-byte hexadecimal object name the client asked to exclude from
|
||||
the resulting pack, claiming to have them already. Can occur zero
|
||||
or more times in the input.
|
||||
|
||||
time float::
|
||||
Number of seconds spent for creating the packfile.
|
||||
|
||||
size decimal::
|
||||
Size of the resulting packfile in bytes.
|
||||
|
||||
kind string:
|
||||
Either "clone" (when the client did not give us any "have", and asked
|
||||
for all our refs with "want"), or "fetch" (otherwise).
|
||||
|
||||
pre-auto-gc
|
||||
-----------
|
||||
~~~~~~~~~~~
|
||||
|
||||
This hook is invoked by 'git-gc --auto'. It takes no parameter, and
|
||||
exiting with non-zero status from this script causes the 'git-gc --auto'
|
||||
|
||||
31
Makefile
31
Makefile
@@ -16,7 +16,7 @@ all::
|
||||
# when attempting to read from an fopen'ed directory.
|
||||
#
|
||||
# Define NO_OPENSSL environment variable if you do not have OpenSSL.
|
||||
# This also implies MOZILLA_SHA1.
|
||||
# This also implies BLK_SHA1.
|
||||
#
|
||||
# Define NO_CURL if you do not have libcurl installed. git-http-pull and
|
||||
# git-http-push are not built, and you cannot use http:// and https://
|
||||
@@ -91,14 +91,6 @@ all::
|
||||
# Define PPC_SHA1 environment variable when running make to make use of
|
||||
# a bundled SHA1 routine optimized for PowerPC.
|
||||
#
|
||||
# Define ARM_SHA1 environment variable when running make to make use of
|
||||
# a bundled SHA1 routine optimized for ARM.
|
||||
#
|
||||
# Define MOZILLA_SHA1 environment variable when running make to make use of
|
||||
# a bundled SHA1 routine coming from Mozilla. It is GPL'd and should be fast
|
||||
# on non-x86 architectures (e.g. PowerPC), while the OpenSSL version (default
|
||||
# choice) has very fast version optimized for i586.
|
||||
#
|
||||
# Define NEEDS_SSL_WITH_CRYPTO if you need -lcrypto with -lssl (Darwin).
|
||||
#
|
||||
# Define NEEDS_LIBICONV if linking with libc is not enough (Darwin).
|
||||
@@ -365,7 +357,6 @@ PROGRAMS += git-patch-id$X
|
||||
PROGRAMS += git-shell$X
|
||||
PROGRAMS += git-show-index$X
|
||||
PROGRAMS += git-unpack-file$X
|
||||
PROGRAMS += git-update-server-info$X
|
||||
PROGRAMS += git-upload-pack$X
|
||||
PROGRAMS += git-var$X
|
||||
|
||||
@@ -644,6 +635,7 @@ BUILTIN_OBJS += builtin-tar-tree.o
|
||||
BUILTIN_OBJS += builtin-unpack-objects.o
|
||||
BUILTIN_OBJS += builtin-update-index.o
|
||||
BUILTIN_OBJS += builtin-update-ref.o
|
||||
BUILTIN_OBJS += builtin-update-server-info.o
|
||||
BUILTIN_OBJS += builtin-upload-archive.o
|
||||
BUILTIN_OBJS += builtin-verify-pack.o
|
||||
BUILTIN_OBJS += builtin-verify-tag.o
|
||||
@@ -757,9 +749,6 @@ ifeq ($(uname_S),SunOS)
|
||||
NO_C99_FORMAT = YesPlease
|
||||
NO_STRTOUMAX = YesPlease
|
||||
endif
|
||||
ifdef NO_IPV6
|
||||
NEEDS_RESOLV = YesPlease
|
||||
endif
|
||||
INSTALL = /usr/ucb/install
|
||||
TAR = gtar
|
||||
BASIC_CFLAGS += -D__EXTENSIONS__ -D__sun__ -DHAVE_ALLOCA_H
|
||||
@@ -928,10 +917,6 @@ else
|
||||
NO_PTHREADS = YesPlease
|
||||
endif
|
||||
endif
|
||||
ifneq (,$(findstring arm,$(uname_M)))
|
||||
ARM_SHA1 = YesPlease
|
||||
NO_MKSTEMPS = YesPlease
|
||||
endif
|
||||
|
||||
-include config.mak.autogen
|
||||
-include config.mak
|
||||
@@ -1024,7 +1009,7 @@ ifndef NO_OPENSSL
|
||||
endif
|
||||
else
|
||||
BASIC_CFLAGS += -DNO_OPENSSL
|
||||
MOZILLA_SHA1 = 1
|
||||
BLK_SHA1 = 1
|
||||
OPENSSL_LIBSSL =
|
||||
endif
|
||||
ifdef NEEDS_SSL_WITH_CRYPTO
|
||||
@@ -1180,21 +1165,11 @@ else
|
||||
ifdef PPC_SHA1
|
||||
SHA1_HEADER = "ppc/sha1.h"
|
||||
LIB_OBJS += ppc/sha1.o ppc/sha1ppc.o
|
||||
else
|
||||
ifdef ARM_SHA1
|
||||
SHA1_HEADER = "arm/sha1.h"
|
||||
LIB_OBJS += arm/sha1.o arm/sha1_arm.o
|
||||
else
|
||||
ifdef MOZILLA_SHA1
|
||||
SHA1_HEADER = "mozilla-sha1/sha1.h"
|
||||
LIB_OBJS += mozilla-sha1/sha1.o
|
||||
else
|
||||
SHA1_HEADER = <openssl/sha.h>
|
||||
EXTLIBS += $(LIB_4_CRYPTO)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
ifdef NO_PERL_MAKEMAKER
|
||||
export NO_PERL_MAKEMAKER
|
||||
endif
|
||||
|
||||
@@ -18,7 +18,7 @@ const char *make_absolute_path(const char *path)
|
||||
{
|
||||
static char bufs[2][PATH_MAX + 1], *buf = bufs[0], *next_buf = bufs[1];
|
||||
char cwd[1024] = "";
|
||||
int buf_index = 1, len;
|
||||
int buf_index = 1;
|
||||
|
||||
int depth = MAXDEPTH;
|
||||
char *last_elem = NULL;
|
||||
@@ -50,7 +50,7 @@ const char *make_absolute_path(const char *path)
|
||||
die_errno ("Could not get current working directory");
|
||||
|
||||
if (last_elem) {
|
||||
int len = strlen(buf);
|
||||
size_t len = strlen(buf);
|
||||
if (len + strlen(last_elem) + 2 > PATH_MAX)
|
||||
die ("Too long path name: '%s/%s'",
|
||||
buf, last_elem);
|
||||
@@ -61,7 +61,7 @@ const char *make_absolute_path(const char *path)
|
||||
}
|
||||
|
||||
if (!lstat(buf, &st) && S_ISLNK(st.st_mode)) {
|
||||
len = readlink(buf, next_buf, PATH_MAX);
|
||||
ssize_t len = readlink(buf, next_buf, PATH_MAX);
|
||||
if (len < 0)
|
||||
die_errno ("Invalid symlink '%s'", buf);
|
||||
if (PATH_MAX <= len)
|
||||
|
||||
82
arm/sha1.c
82
arm/sha1.c
@@ -1,82 +0,0 @@
|
||||
/*
|
||||
* SHA-1 implementation optimized for ARM
|
||||
*
|
||||
* Copyright: (C) 2005 by Nicolas Pitre <nico@cam.org>
|
||||
* Created: September 17, 2005
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "sha1.h"
|
||||
|
||||
extern void arm_sha_transform(uint32_t *hash, const unsigned char *data, uint32_t *W);
|
||||
|
||||
void arm_SHA1_Init(arm_SHA_CTX *c)
|
||||
{
|
||||
c->len = 0;
|
||||
c->hash[0] = 0x67452301;
|
||||
c->hash[1] = 0xefcdab89;
|
||||
c->hash[2] = 0x98badcfe;
|
||||
c->hash[3] = 0x10325476;
|
||||
c->hash[4] = 0xc3d2e1f0;
|
||||
}
|
||||
|
||||
void arm_SHA1_Update(arm_SHA_CTX *c, const void *p, unsigned long n)
|
||||
{
|
||||
uint32_t workspace[80];
|
||||
unsigned int partial;
|
||||
unsigned long done;
|
||||
|
||||
partial = c->len & 0x3f;
|
||||
c->len += n;
|
||||
if ((partial + n) >= 64) {
|
||||
if (partial) {
|
||||
done = 64 - partial;
|
||||
memcpy(c->buffer + partial, p, done);
|
||||
arm_sha_transform(c->hash, c->buffer, workspace);
|
||||
partial = 0;
|
||||
} else
|
||||
done = 0;
|
||||
while (n >= done + 64) {
|
||||
arm_sha_transform(c->hash, p + done, workspace);
|
||||
done += 64;
|
||||
}
|
||||
} else
|
||||
done = 0;
|
||||
if (n - done)
|
||||
memcpy(c->buffer + partial, p + done, n - done);
|
||||
}
|
||||
|
||||
void arm_SHA1_Final(unsigned char *hash, arm_SHA_CTX *c)
|
||||
{
|
||||
uint64_t bitlen;
|
||||
uint32_t bitlen_hi, bitlen_lo;
|
||||
unsigned int i, offset, padlen;
|
||||
unsigned char bits[8];
|
||||
static const unsigned char padding[64] = { 0x80, };
|
||||
|
||||
bitlen = c->len << 3;
|
||||
offset = c->len & 0x3f;
|
||||
padlen = ((offset < 56) ? 56 : (64 + 56)) - offset;
|
||||
arm_SHA1_Update(c, padding, padlen);
|
||||
|
||||
bitlen_hi = bitlen >> 32;
|
||||
bitlen_lo = bitlen & 0xffffffff;
|
||||
bits[0] = bitlen_hi >> 24;
|
||||
bits[1] = bitlen_hi >> 16;
|
||||
bits[2] = bitlen_hi >> 8;
|
||||
bits[3] = bitlen_hi;
|
||||
bits[4] = bitlen_lo >> 24;
|
||||
bits[5] = bitlen_lo >> 16;
|
||||
bits[6] = bitlen_lo >> 8;
|
||||
bits[7] = bitlen_lo;
|
||||
arm_SHA1_Update(c, bits, 8);
|
||||
|
||||
for (i = 0; i < 5; i++) {
|
||||
uint32_t v = c->hash[i];
|
||||
hash[0] = v >> 24;
|
||||
hash[1] = v >> 16;
|
||||
hash[2] = v >> 8;
|
||||
hash[3] = v;
|
||||
hash += 4;
|
||||
}
|
||||
}
|
||||
23
arm/sha1.h
23
arm/sha1.h
@@ -1,23 +0,0 @@
|
||||
/*
|
||||
* SHA-1 implementation optimized for ARM
|
||||
*
|
||||
* Copyright: (C) 2005 by Nicolas Pitre <nico@cam.org>
|
||||
* Created: September 17, 2005
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct {
|
||||
uint64_t len;
|
||||
uint32_t hash[5];
|
||||
unsigned char buffer[64];
|
||||
} arm_SHA_CTX;
|
||||
|
||||
void arm_SHA1_Init(arm_SHA_CTX *c);
|
||||
void arm_SHA1_Update(arm_SHA_CTX *c, const void *p, unsigned long n);
|
||||
void arm_SHA1_Final(unsigned char *hash, arm_SHA_CTX *c);
|
||||
|
||||
#define git_SHA_CTX arm_SHA_CTX
|
||||
#define git_SHA1_Init arm_SHA1_Init
|
||||
#define git_SHA1_Update arm_SHA1_Update
|
||||
#define git_SHA1_Final arm_SHA1_Final
|
||||
183
arm/sha1_arm.S
183
arm/sha1_arm.S
@@ -1,183 +0,0 @@
|
||||
/*
|
||||
* SHA transform optimized for ARM
|
||||
*
|
||||
* Copyright: (C) 2005 by Nicolas Pitre <nico@cam.org>
|
||||
* Created: September 17, 2005
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
.text
|
||||
.globl arm_sha_transform
|
||||
|
||||
/*
|
||||
* void sha_transform(uint32_t *hash, const unsigned char *data, uint32_t *W);
|
||||
*
|
||||
* note: the "data" pointer may be unaligned.
|
||||
*/
|
||||
|
||||
arm_sha_transform:
|
||||
|
||||
stmfd sp!, {r4 - r8, lr}
|
||||
|
||||
@ for (i = 0; i < 16; i++)
|
||||
@ W[i] = ntohl(((uint32_t *)data)[i]);
|
||||
|
||||
#ifdef __ARMEB__
|
||||
mov r4, r0
|
||||
mov r0, r2
|
||||
mov r2, #64
|
||||
bl memcpy
|
||||
mov r2, r0
|
||||
mov r0, r4
|
||||
#else
|
||||
mov r3, r2
|
||||
mov lr, #16
|
||||
1: ldrb r4, [r1], #1
|
||||
ldrb r5, [r1], #1
|
||||
ldrb r6, [r1], #1
|
||||
ldrb r7, [r1], #1
|
||||
subs lr, lr, #1
|
||||
orr r5, r5, r4, lsl #8
|
||||
orr r6, r6, r5, lsl #8
|
||||
orr r7, r7, r6, lsl #8
|
||||
str r7, [r3], #4
|
||||
bne 1b
|
||||
#endif
|
||||
|
||||
@ for (i = 0; i < 64; i++)
|
||||
@ W[i+16] = ror(W[i+13] ^ W[i+8] ^ W[i+2] ^ W[i], 31);
|
||||
|
||||
sub r3, r2, #4
|
||||
mov lr, #64
|
||||
2: ldr r4, [r3, #4]!
|
||||
subs lr, lr, #1
|
||||
ldr r5, [r3, #8]
|
||||
ldr r6, [r3, #32]
|
||||
ldr r7, [r3, #52]
|
||||
eor r4, r4, r5
|
||||
eor r4, r4, r6
|
||||
eor r4, r4, r7
|
||||
mov r4, r4, ror #31
|
||||
str r4, [r3, #64]
|
||||
bne 2b
|
||||
|
||||
/*
|
||||
* The SHA functions are:
|
||||
*
|
||||
* f1(B,C,D) = (D ^ (B & (C ^ D)))
|
||||
* f2(B,C,D) = (B ^ C ^ D)
|
||||
* f3(B,C,D) = ((B & C) | (D & (B | C)))
|
||||
*
|
||||
* Then the sub-blocks are processed as follows:
|
||||
*
|
||||
* A' = ror(A, 27) + f(B,C,D) + E + K + *W++
|
||||
* B' = A
|
||||
* C' = ror(B, 2)
|
||||
* D' = C
|
||||
* E' = D
|
||||
*
|
||||
* We therefore unroll each loop 5 times to avoid register shuffling.
|
||||
* Also the ror for C (and also D and E which are successivelyderived
|
||||
* from it) is applied in place to cut on an additional mov insn for
|
||||
* each round.
|
||||
*/
|
||||
|
||||
.macro sha_f1, A, B, C, D, E
|
||||
ldr r3, [r2], #4
|
||||
eor ip, \C, \D
|
||||
add \E, r1, \E, ror #2
|
||||
and ip, \B, ip, ror #2
|
||||
add \E, \E, \A, ror #27
|
||||
eor ip, ip, \D, ror #2
|
||||
add \E, \E, r3
|
||||
add \E, \E, ip
|
||||
.endm
|
||||
|
||||
.macro sha_f2, A, B, C, D, E
|
||||
ldr r3, [r2], #4
|
||||
add \E, r1, \E, ror #2
|
||||
eor ip, \B, \C, ror #2
|
||||
add \E, \E, \A, ror #27
|
||||
eor ip, ip, \D, ror #2
|
||||
add \E, \E, r3
|
||||
add \E, \E, ip
|
||||
.endm
|
||||
|
||||
.macro sha_f3, A, B, C, D, E
|
||||
ldr r3, [r2], #4
|
||||
add \E, r1, \E, ror #2
|
||||
orr ip, \B, \C, ror #2
|
||||
add \E, \E, \A, ror #27
|
||||
and ip, ip, \D, ror #2
|
||||
add \E, \E, r3
|
||||
and r3, \B, \C, ror #2
|
||||
orr ip, ip, r3
|
||||
add \E, \E, ip
|
||||
.endm
|
||||
|
||||
ldmia r0, {r4 - r8}
|
||||
|
||||
mov lr, #4
|
||||
ldr r1, .L_sha_K + 0
|
||||
|
||||
/* adjust initial values */
|
||||
mov r6, r6, ror #30
|
||||
mov r7, r7, ror #30
|
||||
mov r8, r8, ror #30
|
||||
|
||||
3: subs lr, lr, #1
|
||||
sha_f1 r4, r5, r6, r7, r8
|
||||
sha_f1 r8, r4, r5, r6, r7
|
||||
sha_f1 r7, r8, r4, r5, r6
|
||||
sha_f1 r6, r7, r8, r4, r5
|
||||
sha_f1 r5, r6, r7, r8, r4
|
||||
bne 3b
|
||||
|
||||
ldr r1, .L_sha_K + 4
|
||||
mov lr, #4
|
||||
|
||||
4: subs lr, lr, #1
|
||||
sha_f2 r4, r5, r6, r7, r8
|
||||
sha_f2 r8, r4, r5, r6, r7
|
||||
sha_f2 r7, r8, r4, r5, r6
|
||||
sha_f2 r6, r7, r8, r4, r5
|
||||
sha_f2 r5, r6, r7, r8, r4
|
||||
bne 4b
|
||||
|
||||
ldr r1, .L_sha_K + 8
|
||||
mov lr, #4
|
||||
|
||||
5: subs lr, lr, #1
|
||||
sha_f3 r4, r5, r6, r7, r8
|
||||
sha_f3 r8, r4, r5, r6, r7
|
||||
sha_f3 r7, r8, r4, r5, r6
|
||||
sha_f3 r6, r7, r8, r4, r5
|
||||
sha_f3 r5, r6, r7, r8, r4
|
||||
bne 5b
|
||||
|
||||
ldr r1, .L_sha_K + 12
|
||||
mov lr, #4
|
||||
|
||||
6: subs lr, lr, #1
|
||||
sha_f2 r4, r5, r6, r7, r8
|
||||
sha_f2 r8, r4, r5, r6, r7
|
||||
sha_f2 r7, r8, r4, r5, r6
|
||||
sha_f2 r6, r7, r8, r4, r5
|
||||
sha_f2 r5, r6, r7, r8, r4
|
||||
bne 6b
|
||||
|
||||
ldmia r0, {r1, r2, r3, ip, lr}
|
||||
add r4, r1, r4
|
||||
add r5, r2, r5
|
||||
add r6, r3, r6, ror #2
|
||||
add r7, ip, r7, ror #2
|
||||
add r8, lr, r8, ror #2
|
||||
stmia r0, {r4 - r8}
|
||||
|
||||
ldmfd sp!, {r4 - r8, pc}
|
||||
|
||||
.L_sha_K:
|
||||
.word 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6
|
||||
2
bisect.c
2
bisect.c
@@ -991,7 +991,7 @@ int bisect_next_all(const char *prefix)
|
||||
|
||||
if (!hashcmp(bisect_rev, current_bad_sha1)) {
|
||||
exit_if_skipped_commits(tried, current_bad_sha1);
|
||||
printf("%s is first bad commit\n", bisect_rev_hex);
|
||||
printf("%s is the first bad commit\n", bisect_rev_hex);
|
||||
show_diff_tree(prefix, revs.commits->item);
|
||||
/* This means the bisection process succeeded. */
|
||||
exit(10);
|
||||
|
||||
@@ -1,15 +1,17 @@
|
||||
/*
|
||||
* Based on the Mozilla SHA1 (see mozilla-sha1/sha1.c),
|
||||
* optimized to do word accesses rather than byte accesses,
|
||||
* SHA1 routine optimized to do word accesses rather than byte accesses,
|
||||
* and to avoid unnecessary copies into the context array.
|
||||
*
|
||||
* This was initially based on the Mozilla SHA1 implementation, although
|
||||
* none of the original Mozilla code remains.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <arpa/inet.h>
|
||||
/* this is only to get definitions for memcpy(), ntohl() and htonl() */
|
||||
#include "../git-compat-util.h"
|
||||
|
||||
#include "sha1.h"
|
||||
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
|
||||
|
||||
/*
|
||||
* Force usage of rol or ror by selecting the one with the smaller constant.
|
||||
@@ -54,7 +56,7 @@
|
||||
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
#define setW(x, val) (*(volatile unsigned int *)&W(x) = (val))
|
||||
#elif defined(__arm__)
|
||||
#elif defined(__GNUC__) && defined(__arm__)
|
||||
#define setW(x, val) do { W(x) = (val); __asm__("":::"memory"); } while (0)
|
||||
#else
|
||||
#define setW(x, val) (W(x) = (val))
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
/*
|
||||
* Based on the Mozilla SHA1 (see mozilla-sha1/sha1.h),
|
||||
* optimized to do word accesses rather than byte accesses,
|
||||
* SHA1 routine optimized to do word accesses rather than byte accesses,
|
||||
* and to avoid unnecessary copies into the context array.
|
||||
*
|
||||
* This was initially based on the Mozilla SHA1 implementation, although
|
||||
* none of the original Mozilla code remains.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
unsigned long long size;
|
||||
unsigned int H[5];
|
||||
unsigned int W[16];
|
||||
unsigned long long size;
|
||||
} blk_SHA_CTX;
|
||||
|
||||
void blk_SHA1_Init(blk_SHA_CTX *ctx);
|
||||
|
||||
@@ -105,8 +105,8 @@ static void refresh(int verbose, const char **pathspec)
|
||||
for (specs = 0; pathspec[specs]; specs++)
|
||||
/* nothing */;
|
||||
seen = xcalloc(specs, 1);
|
||||
refresh_index(&the_index, verbose ? REFRESH_SAY_CHANGED : REFRESH_QUIET,
|
||||
pathspec, seen);
|
||||
refresh_index(&the_index, verbose ? REFRESH_IN_PORCELAIN : REFRESH_QUIET,
|
||||
pathspec, seen, "Unstaged changes after refreshing the index:");
|
||||
for (i = 0; i < specs; i++) {
|
||||
if (!seen[i])
|
||||
die("pathspec '%s' did not match any files", pathspec[i]);
|
||||
@@ -131,10 +131,37 @@ static const char **validate_pathspec(int argc, const char **argv, const char *p
|
||||
return pathspec;
|
||||
}
|
||||
|
||||
int run_add_interactive(const char *revision, const char *patch_mode,
|
||||
const char **pathspec)
|
||||
{
|
||||
int status, ac, pc = 0;
|
||||
const char **args;
|
||||
|
||||
if (pathspec)
|
||||
while (pathspec[pc])
|
||||
pc++;
|
||||
|
||||
args = xcalloc(sizeof(const char *), (pc + 5));
|
||||
ac = 0;
|
||||
args[ac++] = "add--interactive";
|
||||
if (patch_mode)
|
||||
args[ac++] = patch_mode;
|
||||
if (revision)
|
||||
args[ac++] = revision;
|
||||
args[ac++] = "--";
|
||||
if (pc) {
|
||||
memcpy(&(args[ac]), pathspec, sizeof(const char *) * pc);
|
||||
ac += pc;
|
||||
}
|
||||
args[ac] = NULL;
|
||||
|
||||
status = run_command_v_opt(args, RUN_GIT_CMD);
|
||||
free(args);
|
||||
return status;
|
||||
}
|
||||
|
||||
int interactive_add(int argc, const char **argv, const char *prefix)
|
||||
{
|
||||
int status, ac;
|
||||
const char **args;
|
||||
const char **pathspec = NULL;
|
||||
|
||||
if (argc) {
|
||||
@@ -143,21 +170,9 @@ int interactive_add(int argc, const char **argv, const char *prefix)
|
||||
return -1;
|
||||
}
|
||||
|
||||
args = xcalloc(sizeof(const char *), (argc + 4));
|
||||
ac = 0;
|
||||
args[ac++] = "add--interactive";
|
||||
if (patch_interactive)
|
||||
args[ac++] = "--patch";
|
||||
args[ac++] = "--";
|
||||
if (argc) {
|
||||
memcpy(&(args[ac]), pathspec, sizeof(const char *) * argc);
|
||||
ac += argc;
|
||||
}
|
||||
args[ac] = NULL;
|
||||
|
||||
status = run_command_v_opt(args, RUN_GIT_CMD);
|
||||
free(args);
|
||||
return status;
|
||||
return run_add_interactive(NULL,
|
||||
patch_interactive ? "--patch" : NULL,
|
||||
pathspec);
|
||||
}
|
||||
|
||||
static int edit_patch(int argc, const char **argv, const char *prefix)
|
||||
|
||||
@@ -1875,18 +1875,16 @@ static int match_fragment(struct image *img,
|
||||
size_t imgoff = 0;
|
||||
size_t preoff = 0;
|
||||
size_t postlen = postimage->len;
|
||||
size_t imglen[preimage->nr];
|
||||
for (i = 0; i < preimage->nr; i++) {
|
||||
size_t prelen = preimage->line[i].len;
|
||||
size_t imglen = img->line[try_lno+i].len;
|
||||
|
||||
imglen[i] = img->line[try_lno+i].len;
|
||||
if (!fuzzy_matchlines(
|
||||
img->buf + try + imgoff, imglen[i],
|
||||
preimage->buf + preoff, prelen))
|
||||
if (!fuzzy_matchlines(img->buf + try + imgoff, imglen,
|
||||
preimage->buf + preoff, prelen))
|
||||
return 0;
|
||||
if (preimage->line[i].flag & LINE_COMMON)
|
||||
postlen += imglen[i] - prelen;
|
||||
imgoff += imglen[i];
|
||||
postlen += imglen - prelen;
|
||||
imgoff += imglen;
|
||||
preoff += prelen;
|
||||
}
|
||||
|
||||
@@ -1900,7 +1898,7 @@ static int match_fragment(struct image *img,
|
||||
fixed_buf = xmalloc(imgoff);
|
||||
memcpy(fixed_buf, img->buf + try, imgoff);
|
||||
for (i = 0; i < preimage->nr; i++)
|
||||
preimage->line[i].len = imglen[i];
|
||||
preimage->line[i].len = img->line[try_lno+i].len;
|
||||
|
||||
/*
|
||||
* Update the preimage buffer and the postimage context lines.
|
||||
|
||||
@@ -1348,7 +1348,7 @@ static void get_ac_line(const char *inbuf, const char *what,
|
||||
/*
|
||||
* Now, convert both name and e-mail using mailmap
|
||||
*/
|
||||
if(map_user(&mailmap, mail+1, mail_len-1, person, tmp-person-1)) {
|
||||
if (map_user(&mailmap, mail+1, mail_len-1, person, tmp-person-1)) {
|
||||
/* Add a trailing '>' to email, since map_user returns plain emails
|
||||
Note: It already has '<', since we replace from mail+1 */
|
||||
mailpos = memchr(mail, '\0', mail_len);
|
||||
|
||||
@@ -586,7 +586,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
|
||||
OPT_BIT('m', NULL, &rename, "move/rename a branch and its reflog", 1),
|
||||
OPT_BIT('M', NULL, &rename, "move/rename a branch, even if target exists", 2),
|
||||
OPT_BOOLEAN('l', NULL, &reflog, "create the branch's reflog"),
|
||||
OPT_BOOLEAN('f', NULL, &force_create, "force creation (when already exists)"),
|
||||
OPT_BOOLEAN('f', "force", &force_create, "force creation (when already exists)"),
|
||||
{
|
||||
OPTION_CALLBACK, 0, "no-merged", &merge_filter_ref,
|
||||
"commit", "print only not merged branches",
|
||||
|
||||
@@ -402,7 +402,9 @@ static int merge_working_tree(struct checkout_opts *opts,
|
||||
topts.dir = xcalloc(1, sizeof(*topts.dir));
|
||||
topts.dir->flags |= DIR_SHOW_IGNORED;
|
||||
topts.dir->exclude_per_dir = ".gitignore";
|
||||
tree = parse_tree_indirect(old->commit->object.sha1);
|
||||
tree = parse_tree_indirect(old->commit ?
|
||||
old->commit->object.sha1 :
|
||||
(unsigned char *)EMPTY_TREE_SHA1_BIN);
|
||||
init_tree_desc(&trees[0], tree->buffer, tree->size);
|
||||
tree = parse_tree_indirect(new->commit->object.sha1);
|
||||
init_tree_desc(&trees[1], tree->buffer, tree->size);
|
||||
@@ -541,14 +543,6 @@ static int switch_branches(struct checkout_opts *opts, struct branch_info *new)
|
||||
parse_commit(new->commit);
|
||||
}
|
||||
|
||||
if (!old.commit && !opts->force) {
|
||||
if (!opts->quiet) {
|
||||
warning("You appear to be on a branch yet to be born.");
|
||||
warning("Forcing checkout of %s.", new->name);
|
||||
}
|
||||
opts->force = 1;
|
||||
}
|
||||
|
||||
ret = merge_working_tree(opts, &old, new);
|
||||
if (ret)
|
||||
return ret;
|
||||
@@ -572,6 +566,13 @@ static int git_checkout_config(const char *var, const char *value, void *cb)
|
||||
return git_xmerge_config(var, value, cb);
|
||||
}
|
||||
|
||||
static int interactive_checkout(const char *revision, const char **pathspec,
|
||||
struct checkout_opts *opts)
|
||||
{
|
||||
return run_add_interactive(revision, "--patch=checkout", pathspec);
|
||||
}
|
||||
|
||||
|
||||
int cmd_checkout(int argc, const char **argv, const char *prefix)
|
||||
{
|
||||
struct checkout_opts opts;
|
||||
@@ -580,6 +581,7 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
|
||||
struct branch_info new;
|
||||
struct tree *source_tree = NULL;
|
||||
char *conflict_style = NULL;
|
||||
int patch_mode = 0;
|
||||
struct option options[] = {
|
||||
OPT__QUIET(&opts.quiet),
|
||||
OPT_STRING('b', NULL, &opts.new_branch, "new branch", "branch"),
|
||||
@@ -590,10 +592,11 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
|
||||
2),
|
||||
OPT_SET_INT('3', "theirs", &opts.writeout_stage, "stage",
|
||||
3),
|
||||
OPT_BOOLEAN('f', NULL, &opts.force, "force"),
|
||||
OPT_BOOLEAN('f', "force", &opts.force, "force"),
|
||||
OPT_BOOLEAN('m', "merge", &opts.merge, "merge"),
|
||||
OPT_STRING(0, "conflict", &conflict_style, "style",
|
||||
"conflict style (merge or diff3)"),
|
||||
OPT_BOOLEAN('p', "patch", &patch_mode, "select hunks interactively"),
|
||||
OPT_END(),
|
||||
};
|
||||
int has_dash_dash;
|
||||
@@ -608,6 +611,10 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
|
||||
argc = parse_options(argc, argv, prefix, options, checkout_usage,
|
||||
PARSE_OPT_KEEP_DASHDASH);
|
||||
|
||||
if (patch_mode && (opts.track > 0 || opts.new_branch
|
||||
|| opts.new_branch_log || opts.merge || opts.force))
|
||||
die ("--patch is incompatible with all other options");
|
||||
|
||||
/* --track without -b should DWIM */
|
||||
if (0 < opts.track && !opts.new_branch) {
|
||||
const char *argv0 = argv[0];
|
||||
@@ -714,6 +721,9 @@ no_reference:
|
||||
if (!pathspec)
|
||||
die("invalid path specification");
|
||||
|
||||
if (patch_mode)
|
||||
return interactive_checkout(new.name, pathspec, &opts);
|
||||
|
||||
/* Checkout paths */
|
||||
if (opts.new_branch) {
|
||||
if (argc == 1) {
|
||||
@@ -729,6 +739,9 @@ no_reference:
|
||||
return checkout_paths(source_tree, pathspec, &opts);
|
||||
}
|
||||
|
||||
if (patch_mode)
|
||||
return interactive_checkout(new.name, NULL, &opts);
|
||||
|
||||
if (opts.new_branch) {
|
||||
struct strbuf buf = STRBUF_INIT;
|
||||
if (strbuf_check_branch_ref(&buf, opts.new_branch))
|
||||
|
||||
@@ -41,7 +41,7 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
|
||||
struct option options[] = {
|
||||
OPT__QUIET(&quiet),
|
||||
OPT__DRY_RUN(&show_only),
|
||||
OPT_BOOLEAN('f', NULL, &force, "force"),
|
||||
OPT_BOOLEAN('f', "force", &force, "force"),
|
||||
OPT_BOOLEAN('d', NULL, &remove_directories,
|
||||
"remove whole directories"),
|
||||
OPT_BOOLEAN('x', NULL, &ignored, "remove ignored files, too"),
|
||||
|
||||
@@ -38,9 +38,10 @@ static const char * const builtin_clone_usage[] = {
|
||||
};
|
||||
|
||||
static int option_quiet, option_no_checkout, option_bare, option_mirror;
|
||||
static int option_local, option_no_hardlinks, option_shared;
|
||||
static int option_local, option_no_hardlinks, option_shared, option_recursive;
|
||||
static char *option_template, *option_reference, *option_depth;
|
||||
static char *option_origin = NULL;
|
||||
static char *option_branch = NULL;
|
||||
static char *option_upload_pack = "git-upload-pack";
|
||||
static int option_verbose;
|
||||
|
||||
@@ -59,12 +60,16 @@ static struct option builtin_clone_options[] = {
|
||||
"don't use local hardlinks, always copy"),
|
||||
OPT_BOOLEAN('s', "shared", &option_shared,
|
||||
"setup as shared repository"),
|
||||
OPT_BOOLEAN(0, "recursive", &option_recursive,
|
||||
"setup as shared repository"),
|
||||
OPT_STRING(0, "template", &option_template, "path",
|
||||
"path the template repository"),
|
||||
OPT_STRING(0, "reference", &option_reference, "repo",
|
||||
"reference repository"),
|
||||
OPT_STRING('o', "origin", &option_origin, "branch",
|
||||
"use <branch> instead of 'origin' to track upstream"),
|
||||
OPT_STRING('b', "branch", &option_branch, "branch",
|
||||
"checkout <branch> instead of the remote's HEAD"),
|
||||
OPT_STRING('u', "upload-pack", &option_upload_pack, "path",
|
||||
"path to git-upload-pack on the remote"),
|
||||
OPT_STRING(0, "depth", &option_depth, "depth",
|
||||
@@ -73,6 +78,10 @@ static struct option builtin_clone_options[] = {
|
||||
OPT_END()
|
||||
};
|
||||
|
||||
static const char *argv_submodule[] = {
|
||||
"submodule", "update", "--init", "--recursive", NULL
|
||||
};
|
||||
|
||||
static char *get_repo_path(const char *repo, int *is_bundle)
|
||||
{
|
||||
static char *suffix[] = { "/.git", ".git", "" };
|
||||
@@ -347,7 +356,9 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
|
||||
const char *repo_name, *repo, *work_tree, *git_dir;
|
||||
char *path, *dir;
|
||||
int dest_exists;
|
||||
const struct ref *refs, *head_points_at, *remote_head, *mapped_refs;
|
||||
const struct ref *refs, *remote_head, *mapped_refs;
|
||||
const struct ref *remote_head_points_at;
|
||||
const struct ref *our_head_points_at;
|
||||
struct strbuf key = STRBUF_INIT, value = STRBUF_INIT;
|
||||
struct strbuf branch_top = STRBUF_INIT, reflog_msg = STRBUF_INIT;
|
||||
struct transport *transport = NULL;
|
||||
@@ -509,7 +520,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
|
||||
option_upload_pack);
|
||||
|
||||
refs = transport_get_remote_refs(transport);
|
||||
if(refs)
|
||||
if (refs)
|
||||
transport_fetch_refs(transport, refs);
|
||||
}
|
||||
|
||||
@@ -519,11 +530,31 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
|
||||
mapped_refs = write_remote_refs(refs, refspec, reflog_msg.buf);
|
||||
|
||||
remote_head = find_ref_by_name(refs, "HEAD");
|
||||
head_points_at = guess_remote_head(remote_head, mapped_refs, 0);
|
||||
remote_head_points_at =
|
||||
guess_remote_head(remote_head, mapped_refs, 0);
|
||||
|
||||
if (option_branch) {
|
||||
struct strbuf head = STRBUF_INIT;
|
||||
strbuf_addstr(&head, src_ref_prefix);
|
||||
strbuf_addstr(&head, option_branch);
|
||||
our_head_points_at =
|
||||
find_ref_by_name(mapped_refs, head.buf);
|
||||
strbuf_release(&head);
|
||||
|
||||
if (!our_head_points_at) {
|
||||
warning("Remote branch %s not found in "
|
||||
"upstream %s, using HEAD instead",
|
||||
option_branch, option_origin);
|
||||
our_head_points_at = remote_head_points_at;
|
||||
}
|
||||
}
|
||||
else
|
||||
our_head_points_at = remote_head_points_at;
|
||||
}
|
||||
else {
|
||||
warning("You appear to have cloned an empty repository.");
|
||||
head_points_at = NULL;
|
||||
our_head_points_at = NULL;
|
||||
remote_head_points_at = NULL;
|
||||
remote_head = NULL;
|
||||
option_no_checkout = 1;
|
||||
if (!option_bare)
|
||||
@@ -531,41 +562,35 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
|
||||
"refs/heads/master");
|
||||
}
|
||||
|
||||
if (head_points_at) {
|
||||
if (remote_head_points_at && !option_bare) {
|
||||
struct strbuf head_ref = STRBUF_INIT;
|
||||
strbuf_addstr(&head_ref, branch_top.buf);
|
||||
strbuf_addstr(&head_ref, "HEAD");
|
||||
create_symref(head_ref.buf,
|
||||
remote_head_points_at->peer_ref->name,
|
||||
reflog_msg.buf);
|
||||
}
|
||||
|
||||
if (our_head_points_at) {
|
||||
/* Local default branch link */
|
||||
create_symref("HEAD", head_points_at->name, NULL);
|
||||
|
||||
create_symref("HEAD", our_head_points_at->name, NULL);
|
||||
if (!option_bare) {
|
||||
struct strbuf head_ref = STRBUF_INIT;
|
||||
const char *head = head_points_at->name;
|
||||
|
||||
if (!prefixcmp(head, "refs/heads/"))
|
||||
head += 11;
|
||||
|
||||
/* Set up the initial local branch */
|
||||
|
||||
/* Local branch initial value */
|
||||
const char *head = skip_prefix(our_head_points_at->name,
|
||||
"refs/heads/");
|
||||
update_ref(reflog_msg.buf, "HEAD",
|
||||
head_points_at->old_sha1,
|
||||
our_head_points_at->old_sha1,
|
||||
NULL, 0, DIE_ON_ERR);
|
||||
|
||||
strbuf_addstr(&head_ref, branch_top.buf);
|
||||
strbuf_addstr(&head_ref, "HEAD");
|
||||
|
||||
/* Remote branch link */
|
||||
create_symref(head_ref.buf,
|
||||
head_points_at->peer_ref->name,
|
||||
reflog_msg.buf);
|
||||
|
||||
install_branch_config(0, head, option_origin,
|
||||
head_points_at->name);
|
||||
our_head_points_at->name);
|
||||
}
|
||||
} else if (remote_head) {
|
||||
/* Source had detached HEAD pointing somewhere. */
|
||||
if (!option_bare)
|
||||
if (!option_bare) {
|
||||
update_ref(reflog_msg.buf, "HEAD",
|
||||
remote_head->old_sha1,
|
||||
NULL, REF_NODEREF, DIE_ON_ERR);
|
||||
our_head_points_at = remote_head;
|
||||
}
|
||||
} else {
|
||||
/* Nothing to checkout out */
|
||||
if (!option_no_checkout)
|
||||
@@ -574,8 +599,10 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
|
||||
option_no_checkout = 1;
|
||||
}
|
||||
|
||||
if (transport)
|
||||
if (transport) {
|
||||
transport_unlock_pack(transport);
|
||||
transport_disconnect(transport);
|
||||
}
|
||||
|
||||
if (!option_no_checkout) {
|
||||
struct lock_file *lock_file = xcalloc(1, sizeof(struct lock_file));
|
||||
@@ -597,7 +624,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
|
||||
opts.src_index = &the_index;
|
||||
opts.dst_index = &the_index;
|
||||
|
||||
tree = parse_tree_indirect(remote_head->old_sha1);
|
||||
tree = parse_tree_indirect(our_head_points_at->old_sha1);
|
||||
parse_tree(tree);
|
||||
init_tree_desc(&t, tree->buffer, tree->size);
|
||||
unpack_trees(1, &t, &opts);
|
||||
@@ -608,6 +635,9 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
|
||||
|
||||
err |= run_hook(NULL, "post-checkout", sha1_to_hex(null_sha1),
|
||||
sha1_to_hex(remote_head->old_sha1), "1", NULL);
|
||||
|
||||
if (!err && option_recursive)
|
||||
err = run_command_v_opt(argv_submodule, RUN_GIT_CMD);
|
||||
}
|
||||
|
||||
strbuf_release(&reflog_msg);
|
||||
|
||||
183
builtin-commit.c
183
builtin-commit.c
@@ -51,7 +51,7 @@ static const char *template_file;
|
||||
static char *edit_message, *use_message;
|
||||
static char *author_name, *author_email, *author_date;
|
||||
static int all, edit_flag, also, interactive, only, amend, signoff;
|
||||
static int quiet, verbose, no_verify, allow_empty;
|
||||
static int quiet, verbose, no_verify, allow_empty, dry_run;
|
||||
static char *untracked_files_arg;
|
||||
/*
|
||||
* The default commit message cleanup mode will remove the lines
|
||||
@@ -103,6 +103,7 @@ static struct option builtin_commit_options[] = {
|
||||
OPT_BOOLEAN(0, "interactive", &interactive, "interactively add files"),
|
||||
OPT_BOOLEAN('o', "only", &only, "commit only specified files"),
|
||||
OPT_BOOLEAN('n', "no-verify", &no_verify, "bypass pre-commit hook"),
|
||||
OPT_BOOLEAN(0, "dry-run", &dry_run, "show what would be committed"),
|
||||
OPT_BOOLEAN(0, "amend", &amend, "amend previous commit"),
|
||||
{ OPTION_STRING, 'u', "untracked-files", &untracked_files_arg, "mode", "show untracked files, optional modes: all, normal, no. (Default: all)", PARSE_OPT_OPTARG, NULL, (intptr_t)"all" },
|
||||
OPT_BOOLEAN(0, "allow-empty", &allow_empty, "ok to record an empty change"),
|
||||
@@ -217,12 +218,15 @@ static void create_base_index(void)
|
||||
exit(128); /* We've already reported the error, finish dying */
|
||||
}
|
||||
|
||||
static char *prepare_index(int argc, const char **argv, const char *prefix)
|
||||
static char *prepare_index(int argc, const char **argv, const char *prefix, int is_status)
|
||||
{
|
||||
int fd;
|
||||
struct string_list partial;
|
||||
const char **pathspec = NULL;
|
||||
int refresh_flags = REFRESH_QUIET;
|
||||
|
||||
if (is_status)
|
||||
refresh_flags |= REFRESH_UNMERGED;
|
||||
if (interactive) {
|
||||
if (interactive_add(argc, argv, prefix) != 0)
|
||||
die("interactive add failed");
|
||||
@@ -253,7 +257,7 @@ static char *prepare_index(int argc, const char **argv, const char *prefix)
|
||||
if (all || (also && pathspec && *pathspec)) {
|
||||
int fd = hold_locked_index(&index_lock, 1);
|
||||
add_files_to_cache(also ? prefix : NULL, pathspec, 0);
|
||||
refresh_cache(REFRESH_QUIET);
|
||||
refresh_cache(refresh_flags);
|
||||
if (write_cache(fd, active_cache, active_nr) ||
|
||||
close_lock_file(&index_lock))
|
||||
die("unable to write new_index file");
|
||||
@@ -272,7 +276,7 @@ static char *prepare_index(int argc, const char **argv, const char *prefix)
|
||||
*/
|
||||
if (!pathspec || !*pathspec) {
|
||||
fd = hold_locked_index(&index_lock, 1);
|
||||
refresh_cache(REFRESH_QUIET);
|
||||
refresh_cache(refresh_flags);
|
||||
if (write_cache(fd, active_cache, active_nr) ||
|
||||
commit_locked_index(&index_lock))
|
||||
die("unable to write new_index file");
|
||||
@@ -339,27 +343,24 @@ static char *prepare_index(int argc, const char **argv, const char *prefix)
|
||||
return false_lock.filename;
|
||||
}
|
||||
|
||||
static int run_status(FILE *fp, const char *index_file, const char *prefix, int nowarn)
|
||||
static int run_status(FILE *fp, const char *index_file, const char *prefix, int nowarn,
|
||||
struct wt_status *s)
|
||||
{
|
||||
struct wt_status s;
|
||||
|
||||
wt_status_prepare(&s);
|
||||
if (wt_status_relative_paths)
|
||||
s.prefix = prefix;
|
||||
if (s->relative_paths)
|
||||
s->prefix = prefix;
|
||||
|
||||
if (amend) {
|
||||
s.amend = 1;
|
||||
s.reference = "HEAD^1";
|
||||
s->amend = 1;
|
||||
s->reference = "HEAD^1";
|
||||
}
|
||||
s.verbose = verbose;
|
||||
s.untracked = (show_untracked_files == SHOW_ALL_UNTRACKED_FILES);
|
||||
s.index_file = index_file;
|
||||
s.fp = fp;
|
||||
s.nowarn = nowarn;
|
||||
s->verbose = verbose;
|
||||
s->index_file = index_file;
|
||||
s->fp = fp;
|
||||
s->nowarn = nowarn;
|
||||
|
||||
wt_status_print(&s);
|
||||
wt_status_print(s);
|
||||
|
||||
return s.commitable;
|
||||
return s->commitable;
|
||||
}
|
||||
|
||||
static int is_a_merge(const unsigned char *sha1)
|
||||
@@ -413,7 +414,8 @@ static void determine_author_info(void)
|
||||
author_date = date;
|
||||
}
|
||||
|
||||
static int prepare_to_commit(const char *index_file, const char *prefix)
|
||||
static int prepare_to_commit(const char *index_file, const char *prefix,
|
||||
struct wt_status *s)
|
||||
{
|
||||
struct stat statbuf;
|
||||
int commitable, saved_color_setting;
|
||||
@@ -555,10 +557,10 @@ static int prepare_to_commit(const char *index_file, const char *prefix)
|
||||
if (ident_shown)
|
||||
fprintf(fp, "#\n");
|
||||
|
||||
saved_color_setting = wt_status_use_color;
|
||||
wt_status_use_color = 0;
|
||||
commitable = run_status(fp, index_file, prefix, 1);
|
||||
wt_status_use_color = saved_color_setting;
|
||||
saved_color_setting = s->use_color;
|
||||
s->use_color = 0;
|
||||
commitable = run_status(fp, index_file, prefix, 1, s);
|
||||
s->use_color = saved_color_setting;
|
||||
} else {
|
||||
unsigned char sha1[20];
|
||||
const char *parent = "HEAD";
|
||||
@@ -579,7 +581,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix)
|
||||
|
||||
if (!commitable && !in_merge && !allow_empty &&
|
||||
!(amend && is_a_merge(head_sha1))) {
|
||||
run_status(stdout, index_file, prefix, 0);
|
||||
run_status(stdout, index_file, prefix, 0, s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -691,7 +693,8 @@ static const char *find_author_by_nickname(const char *name)
|
||||
|
||||
static int parse_and_validate_options(int argc, const char *argv[],
|
||||
const char * const usage[],
|
||||
const char *prefix)
|
||||
const char *prefix,
|
||||
struct wt_status *s)
|
||||
{
|
||||
int f = 0;
|
||||
|
||||
@@ -794,11 +797,11 @@ static int parse_and_validate_options(int argc, const char *argv[],
|
||||
if (!untracked_files_arg)
|
||||
; /* default already initialized */
|
||||
else if (!strcmp(untracked_files_arg, "no"))
|
||||
show_untracked_files = SHOW_NO_UNTRACKED_FILES;
|
||||
s->show_untracked_files = SHOW_NO_UNTRACKED_FILES;
|
||||
else if (!strcmp(untracked_files_arg, "normal"))
|
||||
show_untracked_files = SHOW_NORMAL_UNTRACKED_FILES;
|
||||
s->show_untracked_files = SHOW_NORMAL_UNTRACKED_FILES;
|
||||
else if (!strcmp(untracked_files_arg, "all"))
|
||||
show_untracked_files = SHOW_ALL_UNTRACKED_FILES;
|
||||
s->show_untracked_files = SHOW_ALL_UNTRACKED_FILES;
|
||||
else
|
||||
die("Invalid untracked files mode '%s'", untracked_files_arg);
|
||||
|
||||
@@ -810,30 +813,95 @@ static int parse_and_validate_options(int argc, const char *argv[],
|
||||
return argc;
|
||||
}
|
||||
|
||||
int cmd_status(int argc, const char **argv, const char *prefix)
|
||||
static int dry_run_commit(int argc, const char **argv, const char *prefix,
|
||||
struct wt_status *s)
|
||||
{
|
||||
const char *index_file;
|
||||
int commitable;
|
||||
const char *index_file;
|
||||
|
||||
git_config(git_status_config, NULL);
|
||||
|
||||
if (wt_status_use_color == -1)
|
||||
wt_status_use_color = git_use_color_default;
|
||||
|
||||
if (diff_use_color_default == -1)
|
||||
diff_use_color_default = git_use_color_default;
|
||||
|
||||
argc = parse_and_validate_options(argc, argv, builtin_status_usage, prefix);
|
||||
|
||||
index_file = prepare_index(argc, argv, prefix);
|
||||
|
||||
commitable = run_status(stdout, index_file, prefix, 0);
|
||||
|
||||
index_file = prepare_index(argc, argv, prefix, 1);
|
||||
commitable = run_status(stdout, index_file, prefix, 0, s);
|
||||
rollback_index_files();
|
||||
|
||||
return commitable ? 0 : 1;
|
||||
}
|
||||
|
||||
static int parse_status_slot(const char *var, int offset)
|
||||
{
|
||||
if (!strcasecmp(var+offset, "header"))
|
||||
return WT_STATUS_HEADER;
|
||||
if (!strcasecmp(var+offset, "updated")
|
||||
|| !strcasecmp(var+offset, "added"))
|
||||
return WT_STATUS_UPDATED;
|
||||
if (!strcasecmp(var+offset, "changed"))
|
||||
return WT_STATUS_CHANGED;
|
||||
if (!strcasecmp(var+offset, "untracked"))
|
||||
return WT_STATUS_UNTRACKED;
|
||||
if (!strcasecmp(var+offset, "nobranch"))
|
||||
return WT_STATUS_NOBRANCH;
|
||||
if (!strcasecmp(var+offset, "unmerged"))
|
||||
return WT_STATUS_UNMERGED;
|
||||
die("bad config variable '%s'", var);
|
||||
}
|
||||
|
||||
static int git_status_config(const char *k, const char *v, void *cb)
|
||||
{
|
||||
struct wt_status *s = cb;
|
||||
|
||||
if (!strcmp(k, "status.submodulesummary")) {
|
||||
int is_bool;
|
||||
s->submodule_summary = git_config_bool_or_int(k, v, &is_bool);
|
||||
if (is_bool && s->submodule_summary)
|
||||
s->submodule_summary = -1;
|
||||
return 0;
|
||||
}
|
||||
if (!strcmp(k, "status.color") || !strcmp(k, "color.status")) {
|
||||
s->use_color = git_config_colorbool(k, v, -1);
|
||||
return 0;
|
||||
}
|
||||
if (!prefixcmp(k, "status.color.") || !prefixcmp(k, "color.status.")) {
|
||||
int slot = parse_status_slot(k, 13);
|
||||
if (!v)
|
||||
return config_error_nonbool(k);
|
||||
color_parse(v, k, s->color_palette[slot]);
|
||||
return 0;
|
||||
}
|
||||
if (!strcmp(k, "status.relativepaths")) {
|
||||
s->relative_paths = git_config_bool(k, v);
|
||||
return 0;
|
||||
}
|
||||
if (!strcmp(k, "status.showuntrackedfiles")) {
|
||||
if (!v)
|
||||
return config_error_nonbool(k);
|
||||
else if (!strcmp(v, "no"))
|
||||
s->show_untracked_files = SHOW_NO_UNTRACKED_FILES;
|
||||
else if (!strcmp(v, "normal"))
|
||||
s->show_untracked_files = SHOW_NORMAL_UNTRACKED_FILES;
|
||||
else if (!strcmp(v, "all"))
|
||||
s->show_untracked_files = SHOW_ALL_UNTRACKED_FILES;
|
||||
else
|
||||
return error("Invalid untracked files mode '%s'", v);
|
||||
return 0;
|
||||
}
|
||||
return git_diff_ui_config(k, v, NULL);
|
||||
}
|
||||
|
||||
int cmd_status(int argc, const char **argv, const char *prefix)
|
||||
{
|
||||
struct wt_status s;
|
||||
|
||||
wt_status_prepare(&s);
|
||||
git_config(git_status_config, &s);
|
||||
if (s.use_color == -1)
|
||||
s.use_color = git_use_color_default;
|
||||
if (diff_use_color_default == -1)
|
||||
diff_use_color_default = git_use_color_default;
|
||||
|
||||
argc = parse_and_validate_options(argc, argv, builtin_status_usage,
|
||||
prefix, &s);
|
||||
return dry_run_commit(argc, argv, prefix, &s);
|
||||
}
|
||||
|
||||
static void print_summary(const char *prefix, const unsigned char *sha1)
|
||||
{
|
||||
struct rev_info rev;
|
||||
@@ -883,10 +951,12 @@ static void print_summary(const char *prefix, const unsigned char *sha1)
|
||||
|
||||
static int git_commit_config(const char *k, const char *v, void *cb)
|
||||
{
|
||||
struct wt_status *s = cb;
|
||||
|
||||
if (!strcmp(k, "commit.template"))
|
||||
return git_config_string(&template_file, k, v);
|
||||
|
||||
return git_status_config(k, v, cb);
|
||||
return git_status_config(k, v, s);
|
||||
}
|
||||
|
||||
int cmd_commit(int argc, const char **argv, const char *prefix)
|
||||
@@ -899,19 +969,26 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
|
||||
struct commit_list *parents = NULL, **pptr = &parents;
|
||||
struct stat statbuf;
|
||||
int allow_fast_forward = 1;
|
||||
struct wt_status s;
|
||||
|
||||
git_config(git_commit_config, NULL);
|
||||
wt_status_prepare(&s);
|
||||
git_config(git_commit_config, &s);
|
||||
|
||||
if (wt_status_use_color == -1)
|
||||
wt_status_use_color = git_use_color_default;
|
||||
if (s.use_color == -1)
|
||||
s.use_color = git_use_color_default;
|
||||
|
||||
argc = parse_and_validate_options(argc, argv, builtin_commit_usage, prefix);
|
||||
|
||||
index_file = prepare_index(argc, argv, prefix);
|
||||
argc = parse_and_validate_options(argc, argv, builtin_commit_usage,
|
||||
prefix, &s);
|
||||
if (dry_run) {
|
||||
if (diff_use_color_default == -1)
|
||||
diff_use_color_default = git_use_color_default;
|
||||
return dry_run_commit(argc, argv, prefix, &s);
|
||||
}
|
||||
index_file = prepare_index(argc, argv, prefix, 0);
|
||||
|
||||
/* Set up everything for writing the commit object. This includes
|
||||
running hooks, writing the trees, and interacting with the user. */
|
||||
if (!prepare_to_commit(index_file, prefix)) {
|
||||
if (!prepare_to_commit(index_file, prefix, &s)) {
|
||||
rollback_index_files();
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -576,7 +576,7 @@ static void populate_value(struct refinfo *ref)
|
||||
|
||||
if (!prefixcmp(name, "refname"))
|
||||
refname = ref->refname;
|
||||
else if(!prefixcmp(name, "upstream")) {
|
||||
else if (!prefixcmp(name, "upstream")) {
|
||||
struct branch *branch;
|
||||
/* only local branches may have an upstream */
|
||||
if (prefixcmp(ref->refname, "refs/heads/"))
|
||||
|
||||
@@ -35,6 +35,7 @@ static void cmd_log_init(int argc, const char **argv, const char *prefix,
|
||||
struct rev_info *rev)
|
||||
{
|
||||
int i;
|
||||
int decoration_style = 0;
|
||||
|
||||
rev->abbrev = DEFAULT_ABBREV;
|
||||
rev->commit_format = CMIT_FMT_DEFAULT;
|
||||
@@ -61,8 +62,15 @@ static void cmd_log_init(int argc, const char **argv, const char *prefix,
|
||||
for (i = 1; i < argc; i++) {
|
||||
const char *arg = argv[i];
|
||||
if (!strcmp(arg, "--decorate")) {
|
||||
load_ref_decorations();
|
||||
rev->show_decorations = 1;
|
||||
decoration_style = DECORATE_SHORT_REFS;
|
||||
} else if (!prefixcmp(arg, "--decorate=")) {
|
||||
const char *v = skip_prefix(arg, "--decorate=");
|
||||
if (!strcmp(v, "full"))
|
||||
decoration_style = DECORATE_FULL_REFS;
|
||||
else if (!strcmp(v, "short"))
|
||||
decoration_style = DECORATE_SHORT_REFS;
|
||||
else
|
||||
die("invalid --decorate option: %s", arg);
|
||||
} else if (!strcmp(arg, "--source")) {
|
||||
rev->show_source = 1;
|
||||
} else if (!strcmp(arg, "-h")) {
|
||||
@@ -70,6 +78,10 @@ static void cmd_log_init(int argc, const char **argv, const char *prefix,
|
||||
} else
|
||||
die("unrecognized argument: %s", arg);
|
||||
}
|
||||
if (decoration_style) {
|
||||
rev->show_decorations = 1;
|
||||
load_ref_decorations(decoration_style);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -25,6 +25,7 @@ static enum {
|
||||
static struct strbuf charset = STRBUF_INIT;
|
||||
static int patch_lines;
|
||||
static struct strbuf **p_hdr_data, **s_hdr_data;
|
||||
static int use_scissors;
|
||||
|
||||
#define MAX_HDR_PARSED 10
|
||||
#define MAX_BOUNDARIES 5
|
||||
@@ -712,6 +713,56 @@ static inline int patchbreak(const struct strbuf *line)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int is_scissors_line(const struct strbuf *line)
|
||||
{
|
||||
size_t i, len = line->len;
|
||||
int scissors = 0, gap = 0;
|
||||
int first_nonblank = -1;
|
||||
int last_nonblank = 0, visible, perforation = 0, in_perforation = 0;
|
||||
const char *buf = line->buf;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
if (isspace(buf[i])) {
|
||||
if (in_perforation) {
|
||||
perforation++;
|
||||
gap++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
last_nonblank = i;
|
||||
if (first_nonblank < 0)
|
||||
first_nonblank = i;
|
||||
if (buf[i] == '-') {
|
||||
in_perforation = 1;
|
||||
perforation++;
|
||||
continue;
|
||||
}
|
||||
if (i + 1 < len &&
|
||||
(!memcmp(buf + i, ">8", 2) || !memcmp(buf + i, "8<", 2))) {
|
||||
in_perforation = 1;
|
||||
perforation += 2;
|
||||
scissors += 2;
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
in_perforation = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* The mark must be at least 8 bytes long (e.g. "-- >8 --").
|
||||
* Even though there can be arbitrary cruft on the same line
|
||||
* (e.g. "cut here"), in order to avoid misidentification, the
|
||||
* perforation must occupy more than a third of the visible
|
||||
* width of the line, and dashes and scissors must occupy more
|
||||
* than half of the perforation.
|
||||
*/
|
||||
|
||||
visible = last_nonblank - first_nonblank + 1;
|
||||
return (scissors && 8 <= visible &&
|
||||
visible < perforation * 3 &&
|
||||
gap * 2 < perforation);
|
||||
}
|
||||
|
||||
static int handle_commit_msg(struct strbuf *line)
|
||||
{
|
||||
static int still_looking = 1;
|
||||
@@ -723,7 +774,8 @@ static int handle_commit_msg(struct strbuf *line)
|
||||
strbuf_ltrim(line);
|
||||
if (!line->len)
|
||||
return 0;
|
||||
if ((still_looking = check_header(line, s_hdr_data, 0)) != 0)
|
||||
still_looking = check_header(line, s_hdr_data, 0);
|
||||
if (still_looking)
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -731,6 +783,24 @@ static int handle_commit_msg(struct strbuf *line)
|
||||
if (metainfo_charset)
|
||||
convert_to_utf8(line, charset.buf);
|
||||
|
||||
if (use_scissors && is_scissors_line(line)) {
|
||||
int i;
|
||||
rewind(cmitmsg);
|
||||
ftruncate(fileno(cmitmsg), 0);
|
||||
still_looking = 1;
|
||||
|
||||
/*
|
||||
* We may have already read "secondary headers"; purge
|
||||
* them to give ourselves a clean restart.
|
||||
*/
|
||||
for (i = 0; header[i]; i++) {
|
||||
if (s_hdr_data[i])
|
||||
strbuf_release(s_hdr_data[i]);
|
||||
s_hdr_data[i] = NULL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (patchbreak(line)) {
|
||||
fclose(cmitmsg);
|
||||
cmitmsg = NULL;
|
||||
@@ -885,12 +955,9 @@ static void handle_info(void)
|
||||
fprintf(fout, "\n");
|
||||
}
|
||||
|
||||
static int mailinfo(FILE *in, FILE *out, int ks, const char *encoding,
|
||||
const char *msg, const char *patch)
|
||||
static int mailinfo(FILE *in, FILE *out, const char *msg, const char *patch)
|
||||
{
|
||||
int peek;
|
||||
keep_subject = ks;
|
||||
metainfo_charset = encoding;
|
||||
fin = in;
|
||||
fout = out;
|
||||
|
||||
@@ -924,6 +991,18 @@ static int mailinfo(FILE *in, FILE *out, int ks, const char *encoding,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int git_mailinfo_config(const char *var, const char *value, void *unused)
|
||||
{
|
||||
if (prefixcmp(var, "mailinfo."))
|
||||
return git_default_config(var, value, unused);
|
||||
if (!strcmp(var, "mailinfo.scissors")) {
|
||||
use_scissors = git_config_bool(var, value);
|
||||
return 0;
|
||||
}
|
||||
/* perhaps others here */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char mailinfo_usage[] =
|
||||
"git mailinfo [-k] [-u | --encoding=<encoding> | -n] msg patch <mail >info";
|
||||
|
||||
@@ -934,7 +1013,7 @@ int cmd_mailinfo(int argc, const char **argv, const char *prefix)
|
||||
/* NEEDSWORK: might want to do the optional .git/ directory
|
||||
* discovery
|
||||
*/
|
||||
git_config(git_default_config, NULL);
|
||||
git_config(git_mailinfo_config, NULL);
|
||||
|
||||
def_charset = (git_commit_encoding ? git_commit_encoding : "UTF-8");
|
||||
metainfo_charset = def_charset;
|
||||
@@ -948,6 +1027,10 @@ int cmd_mailinfo(int argc, const char **argv, const char *prefix)
|
||||
metainfo_charset = NULL;
|
||||
else if (!prefixcmp(argv[1], "--encoding="))
|
||||
metainfo_charset = argv[1] + 11;
|
||||
else if (!strcmp(argv[1], "--scissors"))
|
||||
use_scissors = 1;
|
||||
else if (!strcmp(argv[1], "--no-scissors"))
|
||||
use_scissors = 0;
|
||||
else
|
||||
usage(mailinfo_usage);
|
||||
argc--; argv++;
|
||||
@@ -956,5 +1039,5 @@ int cmd_mailinfo(int argc, const char **argv, const char *prefix)
|
||||
if (argc != 3)
|
||||
usage(mailinfo_usage);
|
||||
|
||||
return !!mailinfo(stdin, stdout, keep_subject, metainfo_charset, argv[1], argv[2]);
|
||||
return !!mailinfo(stdin, stdout, argv[1], argv[2]);
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
|
||||
int verbose = 0, show_only = 0, force = 0, ignore_errors = 0;
|
||||
struct option builtin_mv_options[] = {
|
||||
OPT__DRY_RUN(&show_only),
|
||||
OPT_BOOLEAN('f', NULL, &force, "force move/rename even if target exists"),
|
||||
OPT_BOOLEAN('f', "force", &force, "force move/rename even if target exists"),
|
||||
OPT_BOOLEAN('k', NULL, &ignore_errors, "skip move/rename errors"),
|
||||
OPT_END(),
|
||||
};
|
||||
|
||||
@@ -1008,6 +1008,33 @@ static void add_preferred_base(unsigned char *sha1)
|
||||
it->pcache.tree_size = size;
|
||||
}
|
||||
|
||||
static void cleanup_preferred_base(void)
|
||||
{
|
||||
struct pbase_tree *it;
|
||||
unsigned i;
|
||||
|
||||
it = pbase_tree;
|
||||
pbase_tree = NULL;
|
||||
while (it) {
|
||||
struct pbase_tree *this = it;
|
||||
it = this->next;
|
||||
free(this->pcache.tree_data);
|
||||
free(this);
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(pbase_tree_cache); i++) {
|
||||
if (!pbase_tree_cache[i])
|
||||
continue;
|
||||
free(pbase_tree_cache[i]->tree_data);
|
||||
free(pbase_tree_cache[i]);
|
||||
pbase_tree_cache[i] = NULL;
|
||||
}
|
||||
|
||||
free(done_pbase_paths);
|
||||
done_pbase_paths = NULL;
|
||||
done_pbase_paths_num = done_pbase_paths_alloc = 0;
|
||||
}
|
||||
|
||||
static void check_object(struct object_entry *entry)
|
||||
{
|
||||
if (entry->in_pack) {
|
||||
@@ -1599,7 +1626,7 @@ static void *threaded_find_deltas(void *arg)
|
||||
static void ll_find_deltas(struct object_entry **list, unsigned list_size,
|
||||
int window, int depth, unsigned *processed)
|
||||
{
|
||||
struct thread_params p[delta_search_threads];
|
||||
struct thread_params *p;
|
||||
int i, ret, active_threads = 0;
|
||||
|
||||
if (delta_search_threads <= 1) {
|
||||
@@ -1609,6 +1636,7 @@ static void ll_find_deltas(struct object_entry **list, unsigned list_size,
|
||||
if (progress > pack_to_stdout)
|
||||
fprintf(stderr, "Delta compression using up to %d threads.\n",
|
||||
delta_search_threads);
|
||||
p = xcalloc(delta_search_threads, sizeof(*p));
|
||||
|
||||
/* Partition the work amongst work threads. */
|
||||
for (i = 0; i < delta_search_threads; i++) {
|
||||
@@ -1717,6 +1745,7 @@ static void ll_find_deltas(struct object_entry **list, unsigned list_size,
|
||||
active_threads--;
|
||||
}
|
||||
}
|
||||
free(p);
|
||||
}
|
||||
|
||||
#else
|
||||
@@ -1808,7 +1837,7 @@ static void prepare_pack(int window, int depth)
|
||||
|
||||
static int git_pack_config(const char *k, const char *v, void *cb)
|
||||
{
|
||||
if(!strcmp(k, "pack.window")) {
|
||||
if (!strcmp(k, "pack.window")) {
|
||||
window = git_config_int(k, v);
|
||||
return 0;
|
||||
}
|
||||
@@ -2310,6 +2339,7 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
|
||||
rp_av[rp_ac] = NULL;
|
||||
get_object_list(rp_ac, rp_av);
|
||||
}
|
||||
cleanup_preferred_base();
|
||||
if (include_tag && nr_result)
|
||||
for_each_ref(add_ref_tag, NULL);
|
||||
stop_progress(&progress_state);
|
||||
|
||||
@@ -158,9 +158,9 @@ static int do_push(const char *repo, int flags)
|
||||
|
||||
error("failed to push some refs to '%s'", url[i]);
|
||||
if (nonfastforward) {
|
||||
printf("To prevent you from losing history, non-fast-forward updates were rejected.\n"
|
||||
"Merge the remote changes before pushing again.\n"
|
||||
"See 'non-fast forward' section of 'git push --help' for details.\n");
|
||||
printf("To prevent you from losing history, non-fast-forward updates were rejected\n"
|
||||
"Merge the remote changes before pushing again. See the 'non-fast forward'\n"
|
||||
"section of 'git push --help' for details.\n");
|
||||
}
|
||||
errs++;
|
||||
}
|
||||
|
||||
@@ -113,13 +113,15 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix)
|
||||
argc = parse_options(argc, argv, unused_prefix, read_tree_options,
|
||||
read_tree_usage, 0);
|
||||
|
||||
if (read_cache_unmerged() && (opts.prefix || opts.merge))
|
||||
die("You need to resolve your current index first");
|
||||
|
||||
prefix_set = opts.prefix ? 1 : 0;
|
||||
if (1 < opts.merge + opts.reset + prefix_set)
|
||||
die("Which one? -m, --reset, or --prefix?");
|
||||
stage = opts.merge = (opts.reset || opts.merge || prefix_set);
|
||||
|
||||
if (opts.reset || opts.merge || opts.prefix) {
|
||||
if (read_cache_unmerged() && (opts.prefix || opts.merge))
|
||||
die("You need to resolve your current index first");
|
||||
stage = opts.merge = 1;
|
||||
}
|
||||
|
||||
for (i = 0; i < argc; i++) {
|
||||
const char *arg = argv[i];
|
||||
|
||||
@@ -385,7 +385,7 @@ static int get_head_names(const struct ref *remote_refs, struct ref_states *stat
|
||||
get_fetch_map(remote_refs, &refspec, &fetch_map_tail, 0);
|
||||
matches = guess_remote_head(find_ref_by_name(remote_refs, "HEAD"),
|
||||
fetch_map, 1);
|
||||
for(ref = matches; ref; ref = ref->next)
|
||||
for (ref = matches; ref; ref = ref->next)
|
||||
string_list_append(abbrev_branch(ref->name), &states->heads);
|
||||
|
||||
free_refs(fetch_map);
|
||||
@@ -484,7 +484,7 @@ static int read_remote_branches(const char *refname,
|
||||
const char *symref;
|
||||
|
||||
strbuf_addf(&buf, "refs/remotes/%s", rename->old);
|
||||
if(!prefixcmp(refname, buf.buf)) {
|
||||
if (!prefixcmp(refname, buf.buf)) {
|
||||
item = string_list_append(xstrdup(refname), rename->remote_branches);
|
||||
symref = resolve_ref(refname, orig_sha1, 1, &flag);
|
||||
if (flag & REF_ISSYMREF)
|
||||
|
||||
@@ -108,7 +108,8 @@ static int update_index_refresh(int fd, struct lock_file *index_lock, int flags)
|
||||
if (read_cache() < 0)
|
||||
return error("Could not read index");
|
||||
|
||||
result = refresh_cache(flags) ? 1 : 0;
|
||||
result = refresh_index(&the_index, (flags), NULL, NULL,
|
||||
"Unstaged changes after reset:") ? 1 : 0;
|
||||
if (write_cache(fd, active_cache, active_nr) ||
|
||||
commit_locked_index(index_lock))
|
||||
return error ("Could not refresh index");
|
||||
@@ -142,6 +143,17 @@ static void update_index_from_diff(struct diff_queue_struct *q,
|
||||
}
|
||||
}
|
||||
|
||||
static int interactive_reset(const char *revision, const char **argv,
|
||||
const char *prefix)
|
||||
{
|
||||
const char **pathspec = NULL;
|
||||
|
||||
if (*argv)
|
||||
pathspec = get_pathspec(prefix, argv);
|
||||
|
||||
return run_add_interactive(revision, "--patch=reset", pathspec);
|
||||
}
|
||||
|
||||
static int read_from_tree(const char *prefix, const char **argv,
|
||||
unsigned char *tree_sha1, int refresh_flags)
|
||||
{
|
||||
@@ -183,6 +195,7 @@ static void prepend_reflog_action(const char *action, char *buf, size_t size)
|
||||
int cmd_reset(int argc, const char **argv, const char *prefix)
|
||||
{
|
||||
int i = 0, reset_type = NONE, update_ref_status = 0, quiet = 0;
|
||||
int patch_mode = 0;
|
||||
const char *rev = "HEAD";
|
||||
unsigned char sha1[20], *orig = NULL, sha1_orig[20],
|
||||
*old_orig = NULL, sha1_old_orig[20];
|
||||
@@ -198,6 +211,7 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
|
||||
"reset HEAD, index and working tree", MERGE),
|
||||
OPT_BOOLEAN('q', NULL, &quiet,
|
||||
"disable showing new HEAD in hard reset and progress message"),
|
||||
OPT_BOOLEAN('p', "patch", &patch_mode, "select hunks interactively"),
|
||||
OPT_END()
|
||||
};
|
||||
|
||||
@@ -251,6 +265,12 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
|
||||
die("Could not parse object '%s'.", rev);
|
||||
hashcpy(sha1, commit->object.sha1);
|
||||
|
||||
if (patch_mode) {
|
||||
if (reset_type != NONE)
|
||||
die("--patch is incompatible with --{hard,mixed,soft}");
|
||||
return interactive_reset(rev, argv + i, prefix);
|
||||
}
|
||||
|
||||
/* git reset tree [--] paths... can be used to
|
||||
* load chosen paths from the tree into the index without
|
||||
* affecting the working tree nor HEAD. */
|
||||
@@ -261,7 +281,7 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
|
||||
die("Cannot do %s reset with paths.",
|
||||
reset_type_names[reset_type]);
|
||||
return read_from_tree(prefix, argv + i, sha1,
|
||||
quiet ? REFRESH_QUIET : REFRESH_SAY_CHANGED);
|
||||
quiet ? REFRESH_QUIET : REFRESH_IN_PORCELAIN);
|
||||
}
|
||||
if (reset_type == NONE)
|
||||
reset_type = MIXED; /* by default */
|
||||
@@ -302,7 +322,7 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
|
||||
break;
|
||||
case MIXED: /* Report what has not been updated. */
|
||||
update_index_refresh(0, NULL,
|
||||
quiet ? REFRESH_QUIET : REFRESH_SAY_CHANGED);
|
||||
quiet ? REFRESH_QUIET : REFRESH_IN_PORCELAIN);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ static void insert_one_record(struct shortlog *log,
|
||||
/* copy author name to namebuf, to support matching on both name and email */
|
||||
memcpy(namebuf, author, boemail - author);
|
||||
len = boemail - author;
|
||||
while(len > 0 && isspace(namebuf[len-1]))
|
||||
while (len > 0 && isspace(namebuf[len-1]))
|
||||
len--;
|
||||
namebuf[len] = 0;
|
||||
|
||||
|
||||
@@ -390,7 +390,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
|
||||
OPT_BOOLEAN('s', NULL, &sign, "annotated and GPG-signed tag"),
|
||||
OPT_STRING('u', NULL, &keyid, "key-id",
|
||||
"use another key to sign the tag"),
|
||||
OPT_BOOLEAN('f', NULL, &force, "replace the tag if exists"),
|
||||
OPT_BOOLEAN('f', "force", &force, "replace the tag if exists"),
|
||||
|
||||
OPT_GROUP("Tag listing options"),
|
||||
{
|
||||
|
||||
@@ -181,10 +181,10 @@ static void write_cached_object(struct object *obj)
|
||||
static int check_object(struct object *obj, int type, void *data)
|
||||
{
|
||||
if (!obj)
|
||||
return 0;
|
||||
return 1;
|
||||
|
||||
if (obj->flags & FLAG_WRITTEN)
|
||||
return 1;
|
||||
return 0;
|
||||
|
||||
if (type != OBJ_ANY && obj->type != type)
|
||||
die("object type mismatch");
|
||||
@@ -195,22 +195,24 @@ static int check_object(struct object *obj, int type, void *data)
|
||||
if (type != obj->type || type <= 0)
|
||||
die("object of unexpected type");
|
||||
obj->flags |= FLAG_WRITTEN;
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (fsck_object(obj, 1, fsck_error_function))
|
||||
die("Error in object");
|
||||
if (!fsck_walk(obj, check_object, NULL))
|
||||
if (fsck_walk(obj, check_object, NULL))
|
||||
die("Error on reachable objects of %s", sha1_to_hex(obj->sha1));
|
||||
write_cached_object(obj);
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void write_rest(void)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < nr_objects; i++)
|
||||
check_object(obj_list[i].obj, OBJ_ANY, NULL);
|
||||
for (i = 0; i < nr_objects; i++) {
|
||||
if (obj_list[i].obj)
|
||||
check_object(obj_list[i].obj, OBJ_ANY, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void added_object(unsigned nr, enum object_type type,
|
||||
|
||||
25
builtin-update-server-info.c
Normal file
25
builtin-update-server-info.c
Normal file
@@ -0,0 +1,25 @@
|
||||
#include "cache.h"
|
||||
#include "builtin.h"
|
||||
#include "parse-options.h"
|
||||
|
||||
static const char * const update_server_info_usage[] = {
|
||||
"git update-server-info [--force]",
|
||||
NULL
|
||||
};
|
||||
|
||||
int cmd_update_server_info(int argc, const char **argv, const char *prefix)
|
||||
{
|
||||
int force = 0;
|
||||
struct option options[] = {
|
||||
OPT_BOOLEAN('f', "force", &force,
|
||||
"update the info files from scratch"),
|
||||
OPT_END()
|
||||
};
|
||||
|
||||
argc = parse_options(argc, argv, prefix, options,
|
||||
update_server_info_usage, 0);
|
||||
if (argc > 0)
|
||||
usage_with_options(update_server_info_usage, options);
|
||||
|
||||
return !!update_server_info(force);
|
||||
}
|
||||
@@ -102,6 +102,7 @@ extern int cmd_tar_tree(int argc, const char **argv, const char *prefix);
|
||||
extern int cmd_unpack_objects(int argc, const char **argv, const char *prefix);
|
||||
extern int cmd_update_index(int argc, const char **argv, const char *prefix);
|
||||
extern int cmd_update_ref(int argc, const char **argv, const char *prefix);
|
||||
extern int cmd_update_server_info(int argc, const char **argv, const char *prefix);
|
||||
extern int cmd_upload_archive(int argc, const char **argv, const char *prefix);
|
||||
extern int cmd_upload_tar(int argc, const char **argv, const char *prefix);
|
||||
extern int cmd_verify_tag(int argc, const char **argv, const char *prefix);
|
||||
|
||||
13
cache.h
13
cache.h
@@ -330,7 +330,7 @@ static inline void remove_name_hash(struct cache_entry *ce)
|
||||
#define remove_file_from_cache(path) remove_file_from_index(&the_index, (path))
|
||||
#define add_to_cache(path, st, flags) add_to_index(&the_index, (path), (st), (flags))
|
||||
#define add_file_to_cache(path, flags) add_file_to_index(&the_index, (path), (flags))
|
||||
#define refresh_cache(flags) refresh_index(&the_index, (flags), NULL, NULL)
|
||||
#define refresh_cache(flags) refresh_index(&the_index, (flags), NULL, NULL, NULL)
|
||||
#define ce_match_stat(ce, st, options) ie_match_stat(&the_index, (ce), (st), (options))
|
||||
#define ce_modified(ce, st, options) ie_modified(&the_index, (ce), (st), (options))
|
||||
#define cache_name_exists(name, namelen, igncase) index_name_exists(&the_index, (name), (namelen), (igncase))
|
||||
@@ -469,15 +469,15 @@ extern int index_path(unsigned char *sha1, const char *path, struct stat *st, in
|
||||
extern void fill_stat_cache_info(struct cache_entry *ce, struct stat *st);
|
||||
|
||||
/* "careful lstat()" */
|
||||
extern int check_path(const char *path, int len, struct stat *st);
|
||||
extern int check_path(const char *path, int len, struct stat *st, int skiplen);
|
||||
|
||||
#define REFRESH_REALLY 0x0001 /* ignore_valid */
|
||||
#define REFRESH_UNMERGED 0x0002 /* allow unmerged */
|
||||
#define REFRESH_QUIET 0x0004 /* be quiet about it */
|
||||
#define REFRESH_IGNORE_MISSING 0x0008 /* ignore non-existent */
|
||||
#define REFRESH_IGNORE_SUBMODULES 0x0010 /* ignore submodules */
|
||||
#define REFRESH_SAY_CHANGED 0x0020 /* say "changed" not "needs update" */
|
||||
extern int refresh_index(struct index_state *, unsigned int flags, const char **pathspec, char *seen);
|
||||
#define REFRESH_IN_PORCELAIN 0x0020 /* user friendly output, not "needs update" */
|
||||
extern int refresh_index(struct index_state *, unsigned int flags, const char **pathspec, char *seen, char *header_msg);
|
||||
|
||||
struct lock_file {
|
||||
struct lock_file *next;
|
||||
@@ -731,9 +731,14 @@ enum date_mode {
|
||||
};
|
||||
|
||||
const char *show_date(unsigned long time, int timezone, enum date_mode mode);
|
||||
const char *show_date_relative(unsigned long time, int tz,
|
||||
const struct timeval *now,
|
||||
char *timebuf,
|
||||
size_t timebuf_size);
|
||||
int parse_date(const char *date, char *buf, int bufsize);
|
||||
void datestamp(char *buf, int bufsize);
|
||||
unsigned long approxidate(const char *);
|
||||
unsigned long approxidate_relative(const char *date, const struct timeval *now);
|
||||
enum date_mode parse_date_format(const char *format);
|
||||
|
||||
#define IDENT_WARN_ON_NO_NAME 1
|
||||
|
||||
10
commit.c
10
commit.c
@@ -564,13 +564,13 @@ static struct commit_list *merge_bases_many(struct commit *one, int n, struct co
|
||||
while (interesting(list)) {
|
||||
struct commit *commit;
|
||||
struct commit_list *parents;
|
||||
struct commit_list *n;
|
||||
struct commit_list *next;
|
||||
int flags;
|
||||
|
||||
commit = list->item;
|
||||
n = list->next;
|
||||
next = list->next;
|
||||
free(list);
|
||||
list = n;
|
||||
list = next;
|
||||
|
||||
flags = commit->object.flags & (PARENT1 | PARENT2 | STALE);
|
||||
if (flags == (PARENT1 | PARENT2)) {
|
||||
@@ -598,11 +598,11 @@ static struct commit_list *merge_bases_many(struct commit *one, int n, struct co
|
||||
free_commit_list(list);
|
||||
list = result; result = NULL;
|
||||
while (list) {
|
||||
struct commit_list *n = list->next;
|
||||
struct commit_list *next = list->next;
|
||||
if (!(list->item->object.flags & STALE))
|
||||
insert_by_date(list->item, &result);
|
||||
free(list);
|
||||
list = n;
|
||||
list = next;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
2
commit.h
2
commit.h
@@ -140,6 +140,8 @@ int is_descendant_of(struct commit *, struct commit_list *);
|
||||
int in_merge_bases(struct commit *, struct commit **, int);
|
||||
|
||||
extern int interactive_add(int argc, const char **argv, const char *prefix);
|
||||
extern int run_add_interactive(const char *revision, const char *patch_mode,
|
||||
const char **pathspec);
|
||||
|
||||
static inline int single_parent(struct commit *commit)
|
||||
{
|
||||
|
||||
36
compat/bswap.h
Normal file
36
compat/bswap.h
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Let's make sure we always have a sane definition for ntohl()/htonl().
|
||||
* Some libraries define those as a function call, just to perform byte
|
||||
* shifting, bringing significant overhead to what should be a simple
|
||||
* operation.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Default version that the compiler ought to optimize properly with
|
||||
* constant values.
|
||||
*/
|
||||
static inline unsigned int default_swab32(unsigned int val)
|
||||
{
|
||||
return (((val & 0xff000000) >> 24) |
|
||||
((val & 0x00ff0000) >> 8) |
|
||||
((val & 0x0000ff00) << 8) |
|
||||
((val & 0x000000ff) << 24));
|
||||
}
|
||||
|
||||
#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
|
||||
|
||||
#define bswap32(x) ({ \
|
||||
unsigned int __res; \
|
||||
if (__builtin_constant_p(x)) { \
|
||||
__res = default_swab32(x); \
|
||||
} else { \
|
||||
__asm__("bswap %0" : "=r" (__res) : "0" (x)); \
|
||||
} \
|
||||
__res; })
|
||||
|
||||
#undef ntohl
|
||||
#undef htonl
|
||||
#define ntohl(x) bswap32(x)
|
||||
#define htonl(x) bswap32(x)
|
||||
|
||||
#endif
|
||||
10
configure.ac
10
configure.ac
@@ -156,19 +156,11 @@ AC_MSG_NOTICE([CHECKS for site configuration])
|
||||
# tests. These tests take up a significant amount of the total test time
|
||||
# but are not needed unless you plan to talk to SVN repos.
|
||||
#
|
||||
# Define MOZILLA_SHA1 environment variable when running make to make use of
|
||||
# a bundled SHA1 routine coming from Mozilla. It is GPL'd and should be fast
|
||||
# on non-x86 architectures (e.g. PowerPC), while the OpenSSL version (default
|
||||
# choice) has very fast version optimized for i586.
|
||||
#
|
||||
# Define PPC_SHA1 environment variable when running make to make use of
|
||||
# a bundled SHA1 routine optimized for PowerPC.
|
||||
#
|
||||
# Define ARM_SHA1 environment variable when running make to make use of
|
||||
# a bundled SHA1 routine optimized for ARM.
|
||||
#
|
||||
# Define NO_OPENSSL environment variable if you do not have OpenSSL.
|
||||
# This also implies MOZILLA_SHA1.
|
||||
# This also implies BLK_SHA1.
|
||||
#
|
||||
# Define OPENSSLDIR=/foo/bar if your openssl header and library files are in
|
||||
# /foo/bar/include and /foo/bar/lib directories.
|
||||
|
||||
@@ -513,7 +513,7 @@ struct child_process *git_connect(int fd[2], const char *url_orig,
|
||||
signal(SIGCHLD, SIG_DFL);
|
||||
|
||||
host = strstr(url, "://");
|
||||
if(host) {
|
||||
if (host) {
|
||||
*host = '\0';
|
||||
protocol = get_protocol(url);
|
||||
host += 3;
|
||||
|
||||
280
date.c
280
date.c
@@ -24,6 +24,8 @@ time_t tm_to_time_t(const struct tm *tm)
|
||||
return -1;
|
||||
if (month < 2 || (year + 2) % 4)
|
||||
day--;
|
||||
if (tm->tm_hour < 0 || tm->tm_min < 0 || tm->tm_sec < 0)
|
||||
return -1;
|
||||
return (year * 365 + (year + 1) / 4 + mdays[month] + day) * 24*60*60UL +
|
||||
tm->tm_hour * 60*60 + tm->tm_min * 60 + tm->tm_sec;
|
||||
}
|
||||
@@ -84,6 +86,67 @@ static int local_tzoffset(unsigned long time)
|
||||
return offset * eastwest;
|
||||
}
|
||||
|
||||
const char *show_date_relative(unsigned long time, int tz,
|
||||
const struct timeval *now,
|
||||
char *timebuf,
|
||||
size_t timebuf_size)
|
||||
{
|
||||
unsigned long diff;
|
||||
if (now->tv_sec < time)
|
||||
return "in the future";
|
||||
diff = now->tv_sec - time;
|
||||
if (diff < 90) {
|
||||
snprintf(timebuf, timebuf_size, "%lu seconds ago", diff);
|
||||
return timebuf;
|
||||
}
|
||||
/* Turn it into minutes */
|
||||
diff = (diff + 30) / 60;
|
||||
if (diff < 90) {
|
||||
snprintf(timebuf, timebuf_size, "%lu minutes ago", diff);
|
||||
return timebuf;
|
||||
}
|
||||
/* Turn it into hours */
|
||||
diff = (diff + 30) / 60;
|
||||
if (diff < 36) {
|
||||
snprintf(timebuf, timebuf_size, "%lu hours ago", diff);
|
||||
return timebuf;
|
||||
}
|
||||
/* We deal with number of days from here on */
|
||||
diff = (diff + 12) / 24;
|
||||
if (diff < 14) {
|
||||
snprintf(timebuf, timebuf_size, "%lu days ago", diff);
|
||||
return timebuf;
|
||||
}
|
||||
/* Say weeks for the past 10 weeks or so */
|
||||
if (diff < 70) {
|
||||
snprintf(timebuf, timebuf_size, "%lu weeks ago", (diff + 3) / 7);
|
||||
return timebuf;
|
||||
}
|
||||
/* Say months for the past 12 months or so */
|
||||
if (diff < 360) {
|
||||
snprintf(timebuf, timebuf_size, "%lu months ago", (diff + 15) / 30);
|
||||
return timebuf;
|
||||
}
|
||||
/* Give years and months for 5 years or so */
|
||||
if (diff < 1825) {
|
||||
unsigned long years = diff / 365;
|
||||
unsigned long months = (diff % 365 + 15) / 30;
|
||||
int n;
|
||||
n = snprintf(timebuf, timebuf_size, "%lu year%s",
|
||||
years, (years > 1 ? "s" : ""));
|
||||
if (months)
|
||||
snprintf(timebuf + n, timebuf_size - n,
|
||||
", %lu month%s ago",
|
||||
months, (months > 1 ? "s" : ""));
|
||||
else
|
||||
snprintf(timebuf + n, timebuf_size - n, " ago");
|
||||
return timebuf;
|
||||
}
|
||||
/* Otherwise, just years. Centuries is probably overkill. */
|
||||
snprintf(timebuf, timebuf_size, "%lu years ago", (diff + 183) / 365);
|
||||
return timebuf;
|
||||
}
|
||||
|
||||
const char *show_date(unsigned long time, int tz, enum date_mode mode)
|
||||
{
|
||||
struct tm *tm;
|
||||
@@ -95,63 +158,10 @@ const char *show_date(unsigned long time, int tz, enum date_mode mode)
|
||||
}
|
||||
|
||||
if (mode == DATE_RELATIVE) {
|
||||
unsigned long diff;
|
||||
struct timeval now;
|
||||
gettimeofday(&now, NULL);
|
||||
if (now.tv_sec < time)
|
||||
return "in the future";
|
||||
diff = now.tv_sec - time;
|
||||
if (diff < 90) {
|
||||
snprintf(timebuf, sizeof(timebuf), "%lu seconds ago", diff);
|
||||
return timebuf;
|
||||
}
|
||||
/* Turn it into minutes */
|
||||
diff = (diff + 30) / 60;
|
||||
if (diff < 90) {
|
||||
snprintf(timebuf, sizeof(timebuf), "%lu minutes ago", diff);
|
||||
return timebuf;
|
||||
}
|
||||
/* Turn it into hours */
|
||||
diff = (diff + 30) / 60;
|
||||
if (diff < 36) {
|
||||
snprintf(timebuf, sizeof(timebuf), "%lu hours ago", diff);
|
||||
return timebuf;
|
||||
}
|
||||
/* We deal with number of days from here on */
|
||||
diff = (diff + 12) / 24;
|
||||
if (diff < 14) {
|
||||
snprintf(timebuf, sizeof(timebuf), "%lu days ago", diff);
|
||||
return timebuf;
|
||||
}
|
||||
/* Say weeks for the past 10 weeks or so */
|
||||
if (diff < 70) {
|
||||
snprintf(timebuf, sizeof(timebuf), "%lu weeks ago", (diff + 3) / 7);
|
||||
return timebuf;
|
||||
}
|
||||
/* Say months for the past 12 months or so */
|
||||
if (diff < 360) {
|
||||
snprintf(timebuf, sizeof(timebuf), "%lu months ago", (diff + 15) / 30);
|
||||
return timebuf;
|
||||
}
|
||||
/* Give years and months for 5 years or so */
|
||||
if (diff < 1825) {
|
||||
unsigned long years = (diff + 183) / 365;
|
||||
unsigned long months = (diff % 365 + 15) / 30;
|
||||
int n;
|
||||
n = snprintf(timebuf, sizeof(timebuf), "%lu year%s",
|
||||
years, (years > 1 ? "s" : ""));
|
||||
if (months)
|
||||
snprintf(timebuf + n, sizeof(timebuf) - n,
|
||||
", %lu month%s ago",
|
||||
months, (months > 1 ? "s" : ""));
|
||||
else
|
||||
snprintf(timebuf + n, sizeof(timebuf) - n,
|
||||
" ago");
|
||||
return timebuf;
|
||||
}
|
||||
/* Otherwise, just years. Centuries is probably overkill. */
|
||||
snprintf(timebuf, sizeof(timebuf), "%lu years ago", (diff + 183) / 365);
|
||||
return timebuf;
|
||||
return show_date_relative(time, tz, &now,
|
||||
timebuf, sizeof(timebuf));
|
||||
}
|
||||
|
||||
if (mode == DATE_LOCAL)
|
||||
@@ -425,13 +435,19 @@ static int match_multi_number(unsigned long num, char c, const char *date, char
|
||||
return end - date;
|
||||
}
|
||||
|
||||
/* Have we filled in any part of the time/date yet? */
|
||||
/*
|
||||
* Have we filled in any part of the time/date yet?
|
||||
* We just do a binary 'and' to see if the sign bit
|
||||
* is set in all the values.
|
||||
*/
|
||||
static inline int nodate(struct tm *tm)
|
||||
{
|
||||
return tm->tm_year < 0 &&
|
||||
tm->tm_mon < 0 &&
|
||||
tm->tm_mday < 0 &&
|
||||
!(tm->tm_hour | tm->tm_min | tm->tm_sec);
|
||||
return (tm->tm_year &
|
||||
tm->tm_mon &
|
||||
tm->tm_mday &
|
||||
tm->tm_hour &
|
||||
tm->tm_min &
|
||||
tm->tm_sec) < 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -525,11 +541,8 @@ static int match_digit(const char *date, struct tm *tm, int *offset, int *tm_gmt
|
||||
}
|
||||
}
|
||||
|
||||
if (num > 0 && num < 32) {
|
||||
tm->tm_mday = num;
|
||||
} else if (num > 0 && num < 13) {
|
||||
if (num > 0 && num < 13 && tm->tm_mon < 0)
|
||||
tm->tm_mon = num-1;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
@@ -583,6 +596,9 @@ int parse_date(const char *date, char *result, int maxlen)
|
||||
tm.tm_mon = -1;
|
||||
tm.tm_mday = -1;
|
||||
tm.tm_isdst = -1;
|
||||
tm.tm_hour = -1;
|
||||
tm.tm_min = -1;
|
||||
tm.tm_sec = -1;
|
||||
offset = -1;
|
||||
tm_gmt = 0;
|
||||
|
||||
@@ -657,42 +673,59 @@ void datestamp(char *buf, int bufsize)
|
||||
date_string(now, offset, buf, bufsize);
|
||||
}
|
||||
|
||||
static void update_tm(struct tm *tm, unsigned long sec)
|
||||
/*
|
||||
* Relative time update (eg "2 days ago"). If we haven't set the time
|
||||
* yet, we need to set it from current time.
|
||||
*/
|
||||
static unsigned long update_tm(struct tm *tm, struct tm *now, unsigned long sec)
|
||||
{
|
||||
time_t n = mktime(tm) - sec;
|
||||
time_t n;
|
||||
|
||||
if (tm->tm_mday < 0)
|
||||
tm->tm_mday = now->tm_mday;
|
||||
if (tm->tm_mon < 0)
|
||||
tm->tm_mon = now->tm_mon;
|
||||
if (tm->tm_year < 0) {
|
||||
tm->tm_year = now->tm_year;
|
||||
if (tm->tm_mon > now->tm_mon)
|
||||
tm->tm_year--;
|
||||
}
|
||||
|
||||
n = mktime(tm) - sec;
|
||||
localtime_r(&n, tm);
|
||||
return n;
|
||||
}
|
||||
|
||||
static void date_yesterday(struct tm *tm, int *num)
|
||||
static void date_yesterday(struct tm *tm, struct tm *now, int *num)
|
||||
{
|
||||
update_tm(tm, 24*60*60);
|
||||
update_tm(tm, now, 24*60*60);
|
||||
}
|
||||
|
||||
static void date_time(struct tm *tm, int hour)
|
||||
static void date_time(struct tm *tm, struct tm *now, int hour)
|
||||
{
|
||||
if (tm->tm_hour < hour)
|
||||
date_yesterday(tm, NULL);
|
||||
date_yesterday(tm, now, NULL);
|
||||
tm->tm_hour = hour;
|
||||
tm->tm_min = 0;
|
||||
tm->tm_sec = 0;
|
||||
}
|
||||
|
||||
static void date_midnight(struct tm *tm, int *num)
|
||||
static void date_midnight(struct tm *tm, struct tm *now, int *num)
|
||||
{
|
||||
date_time(tm, 0);
|
||||
date_time(tm, now, 0);
|
||||
}
|
||||
|
||||
static void date_noon(struct tm *tm, int *num)
|
||||
static void date_noon(struct tm *tm, struct tm *now, int *num)
|
||||
{
|
||||
date_time(tm, 12);
|
||||
date_time(tm, now, 12);
|
||||
}
|
||||
|
||||
static void date_tea(struct tm *tm, int *num)
|
||||
static void date_tea(struct tm *tm, struct tm *now, int *num)
|
||||
{
|
||||
date_time(tm, 17);
|
||||
date_time(tm, now, 17);
|
||||
}
|
||||
|
||||
static void date_pm(struct tm *tm, int *num)
|
||||
static void date_pm(struct tm *tm, struct tm *now, int *num)
|
||||
{
|
||||
int hour, n = *num;
|
||||
*num = 0;
|
||||
@@ -706,7 +739,7 @@ static void date_pm(struct tm *tm, int *num)
|
||||
tm->tm_hour = (hour % 12) + 12;
|
||||
}
|
||||
|
||||
static void date_am(struct tm *tm, int *num)
|
||||
static void date_am(struct tm *tm, struct tm *now, int *num)
|
||||
{
|
||||
int hour, n = *num;
|
||||
*num = 0;
|
||||
@@ -720,7 +753,7 @@ static void date_am(struct tm *tm, int *num)
|
||||
tm->tm_hour = (hour % 12);
|
||||
}
|
||||
|
||||
static void date_never(struct tm *tm, int *num)
|
||||
static void date_never(struct tm *tm, struct tm *now, int *num)
|
||||
{
|
||||
time_t n = 0;
|
||||
localtime_r(&n, tm);
|
||||
@@ -728,7 +761,7 @@ static void date_never(struct tm *tm, int *num)
|
||||
|
||||
static const struct special {
|
||||
const char *name;
|
||||
void (*fn)(struct tm *, int *);
|
||||
void (*fn)(struct tm *, struct tm *, int *);
|
||||
} special[] = {
|
||||
{ "yesterday", date_yesterday },
|
||||
{ "noon", date_noon },
|
||||
@@ -757,7 +790,7 @@ static const struct typelen {
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
static const char *approxidate_alpha(const char *date, struct tm *tm, int *num)
|
||||
static const char *approxidate_alpha(const char *date, struct tm *tm, struct tm *now, int *num)
|
||||
{
|
||||
const struct typelen *tl;
|
||||
const struct special *s;
|
||||
@@ -778,7 +811,7 @@ static const char *approxidate_alpha(const char *date, struct tm *tm, int *num)
|
||||
for (s = special; s->name; s++) {
|
||||
int len = strlen(s->name);
|
||||
if (match_string(date, s->name) == len) {
|
||||
s->fn(tm, num);
|
||||
s->fn(tm, now, num);
|
||||
return end;
|
||||
}
|
||||
}
|
||||
@@ -800,7 +833,7 @@ static const char *approxidate_alpha(const char *date, struct tm *tm, int *num)
|
||||
while (tl->type) {
|
||||
int len = strlen(tl->type);
|
||||
if (match_string(date, tl->type) >= len-1) {
|
||||
update_tm(tm, tl->length * *num);
|
||||
update_tm(tm, now, tl->length * *num);
|
||||
*num = 0;
|
||||
return end;
|
||||
}
|
||||
@@ -818,13 +851,15 @@ static const char *approxidate_alpha(const char *date, struct tm *tm, int *num)
|
||||
n++;
|
||||
diff += 7*n;
|
||||
|
||||
update_tm(tm, diff * 24 * 60 * 60);
|
||||
update_tm(tm, now, diff * 24 * 60 * 60);
|
||||
return end;
|
||||
}
|
||||
}
|
||||
|
||||
if (match_string(date, "months") >= 5) {
|
||||
int n = tm->tm_mon - *num;
|
||||
int n;
|
||||
update_tm(tm, now, 0); /* fill in date fields if needed */
|
||||
n = tm->tm_mon - *num;
|
||||
*num = 0;
|
||||
while (n < 0) {
|
||||
n += 12;
|
||||
@@ -835,6 +870,7 @@ static const char *approxidate_alpha(const char *date, struct tm *tm, int *num)
|
||||
}
|
||||
|
||||
if (match_string(date, "years") >= 4) {
|
||||
update_tm(tm, now, 0); /* fill in date fields if needed */
|
||||
tm->tm_year -= *num;
|
||||
*num = 0;
|
||||
return end;
|
||||
@@ -866,36 +902,82 @@ static const char *approxidate_digit(const char *date, struct tm *tm, int *num)
|
||||
return end;
|
||||
}
|
||||
|
||||
unsigned long approxidate(const char *date)
|
||||
/*
|
||||
* Do we have a pending number at the end, or when
|
||||
* we see a new one? Let's assume it's a month day,
|
||||
* as in "Dec 6, 1992"
|
||||
*/
|
||||
static void pending_number(struct tm *tm, int *num)
|
||||
{
|
||||
int number = *num;
|
||||
|
||||
if (number) {
|
||||
*num = 0;
|
||||
if (tm->tm_mday < 0 && number < 32)
|
||||
tm->tm_mday = number;
|
||||
else if (tm->tm_mon < 0 && number < 13)
|
||||
tm->tm_mon = number-1;
|
||||
else if (tm->tm_year < 0) {
|
||||
if (number > 1969 && number < 2100)
|
||||
tm->tm_year = number - 1900;
|
||||
else if (number > 69 && number < 100)
|
||||
tm->tm_year = number;
|
||||
else if (number < 38)
|
||||
tm->tm_year = 100 + number;
|
||||
/* We screw up for number = 00 ? */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned long approxidate_str(const char *date, const struct timeval *tv)
|
||||
{
|
||||
int number = 0;
|
||||
struct tm tm, now;
|
||||
struct timeval tv;
|
||||
time_t time_sec;
|
||||
char buffer[50];
|
||||
|
||||
if (parse_date(date, buffer, sizeof(buffer)) > 0)
|
||||
return strtoul(buffer, NULL, 10);
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
time_sec = tv.tv_sec;
|
||||
time_sec = tv->tv_sec;
|
||||
localtime_r(&time_sec, &tm);
|
||||
now = tm;
|
||||
|
||||
tm.tm_year = -1;
|
||||
tm.tm_mon = -1;
|
||||
tm.tm_mday = -1;
|
||||
|
||||
for (;;) {
|
||||
unsigned char c = *date;
|
||||
if (!c)
|
||||
break;
|
||||
date++;
|
||||
if (isdigit(c)) {
|
||||
pending_number(&tm, &number);
|
||||
date = approxidate_digit(date-1, &tm, &number);
|
||||
continue;
|
||||
}
|
||||
if (isalpha(c))
|
||||
date = approxidate_alpha(date-1, &tm, &number);
|
||||
date = approxidate_alpha(date-1, &tm, &now, &number);
|
||||
}
|
||||
if (number > 0 && number < 32)
|
||||
tm.tm_mday = number;
|
||||
if (tm.tm_mon > now.tm_mon && tm.tm_year == now.tm_year)
|
||||
tm.tm_year--;
|
||||
return mktime(&tm);
|
||||
pending_number(&tm, &number);
|
||||
return update_tm(&tm, &now, 0);
|
||||
}
|
||||
|
||||
unsigned long approxidate_relative(const char *date, const struct timeval *tv)
|
||||
{
|
||||
char buffer[50];
|
||||
|
||||
if (parse_date(date, buffer, sizeof(buffer)) > 0)
|
||||
return strtoul(buffer, NULL, 0);
|
||||
|
||||
return approxidate_str(date, tv);
|
||||
}
|
||||
|
||||
unsigned long approxidate(const char *date)
|
||||
{
|
||||
struct timeval tv;
|
||||
char buffer[50];
|
||||
|
||||
if (parse_date(date, buffer, sizeof(buffer)) > 0)
|
||||
return strtoul(buffer, NULL, 0);
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
return approxidate_str(date, &tv);
|
||||
}
|
||||
|
||||
28
diff-lib.c
28
diff-lib.c
@@ -162,7 +162,8 @@ int run_diff_files(struct rev_info *revs, unsigned int option)
|
||||
if (ce_uptodate(ce))
|
||||
continue;
|
||||
|
||||
changed = check_removed(ce, &st);
|
||||
/* If CE_VALID is set, don't look at workdir for file removal */
|
||||
changed = (ce->ce_flags & CE_VALID) ? 0 : check_removed(ce, &st);
|
||||
if (changed) {
|
||||
if (changed < 0) {
|
||||
perror(ce->name);
|
||||
@@ -308,22 +309,6 @@ static int show_modified(struct rev_info *revs,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This turns all merge entries into "stage 3". That guarantees that
|
||||
* when we read in the new tree (into "stage 1"), we won't lose sight
|
||||
* of the fact that we had unmerged entries.
|
||||
*/
|
||||
static void mark_merge_entries(void)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < active_nr; i++) {
|
||||
struct cache_entry *ce = active_cache[i];
|
||||
if (!ce_stage(ce))
|
||||
continue;
|
||||
ce->ce_flags |= CE_STAGEMASK;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This gets a mix of an existing index and a tree, one pathname entry
|
||||
* at a time. The index entry may be a single stage-0 one, but it could
|
||||
@@ -337,6 +322,8 @@ static void do_oneway_diff(struct unpack_trees_options *o,
|
||||
struct rev_info *revs = o->unpack_data;
|
||||
int match_missing, cached;
|
||||
|
||||
/* if the entry is not checked out, don't examine work tree */
|
||||
cached = o->index_only || (idx && (idx->ce_flags & CE_VALID));
|
||||
/*
|
||||
* Backward compatibility wart - "diff-index -m" does
|
||||
* not mean "do not ignore merges", but "match_missing".
|
||||
@@ -344,12 +331,11 @@ static void do_oneway_diff(struct unpack_trees_options *o,
|
||||
* But with the revision flag parsing, that's found in
|
||||
* "!revs->ignore_merges".
|
||||
*/
|
||||
cached = o->index_only;
|
||||
match_missing = !revs->ignore_merges;
|
||||
|
||||
if (cached && idx && ce_stage(idx)) {
|
||||
if (tree)
|
||||
diff_unmerge(&revs->diffopt, idx->name, idx->ce_mode, idx->sha1);
|
||||
diff_unmerge(&revs->diffopt, idx->name, idx->ce_mode,
|
||||
idx->sha1);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -435,8 +421,6 @@ int run_diff_index(struct rev_info *revs, int cached)
|
||||
struct unpack_trees_options opts;
|
||||
struct tree_desc t;
|
||||
|
||||
mark_merge_entries();
|
||||
|
||||
ent = revs->pending.objects[0].item;
|
||||
tree_name = revs->pending.objects[0].name;
|
||||
tree = parse_tree_indirect(ent->sha1);
|
||||
|
||||
2
diff.c
2
diff.c
@@ -2691,7 +2691,7 @@ static int parse_num(const char **cp_p)
|
||||
num = 0;
|
||||
scale = 1;
|
||||
dot = 0;
|
||||
for(;;) {
|
||||
for (;;) {
|
||||
ch = *cp;
|
||||
if ( !dot && ch == '.' ) {
|
||||
scale = 1;
|
||||
|
||||
12
entry.c
12
entry.c
@@ -177,11 +177,15 @@ static int write_entry(struct cache_entry *ce, char *path, const struct checkout
|
||||
|
||||
/*
|
||||
* This is like 'lstat()', except it refuses to follow symlinks
|
||||
* in the path.
|
||||
* in the path, after skipping "skiplen".
|
||||
*/
|
||||
int check_path(const char *path, int len, struct stat *st)
|
||||
int check_path(const char *path, int len, struct stat *st, int skiplen)
|
||||
{
|
||||
if (has_symlink_leading_path(path, len)) {
|
||||
const char *slash = path + len;
|
||||
|
||||
while (path < slash && *slash != '/')
|
||||
slash--;
|
||||
if (!has_dirs_only_path(path, slash - path, skiplen)) {
|
||||
errno = ENOENT;
|
||||
return -1;
|
||||
}
|
||||
@@ -201,7 +205,7 @@ int checkout_entry(struct cache_entry *ce, const struct checkout *state, char *t
|
||||
strcpy(path + len, ce->name);
|
||||
len += ce_namelen(ce);
|
||||
|
||||
if (!check_path(path, len, &st)) {
|
||||
if (!check_path(path, len, &st, state->base_dir_len)) {
|
||||
unsigned changed = ce_match_stat(ce, &st, CE_MATCH_IGNORE_VALID);
|
||||
if (!changed)
|
||||
return 0;
|
||||
|
||||
@@ -72,6 +72,79 @@ sub colored {
|
||||
|
||||
# command line options
|
||||
my $patch_mode;
|
||||
my $patch_mode_revision;
|
||||
|
||||
sub apply_patch;
|
||||
sub apply_patch_for_checkout_commit;
|
||||
sub apply_patch_for_stash;
|
||||
|
||||
my %patch_modes = (
|
||||
'stage' => {
|
||||
DIFF => 'diff-files -p',
|
||||
APPLY => sub { apply_patch 'apply --cached', @_; },
|
||||
APPLY_CHECK => 'apply --cached',
|
||||
VERB => 'Stage',
|
||||
TARGET => '',
|
||||
PARTICIPLE => 'staging',
|
||||
FILTER => 'file-only',
|
||||
},
|
||||
'stash' => {
|
||||
DIFF => 'diff-index -p HEAD',
|
||||
APPLY => sub { apply_patch 'apply --cached', @_; },
|
||||
APPLY_CHECK => 'apply --cached',
|
||||
VERB => 'Stash',
|
||||
TARGET => '',
|
||||
PARTICIPLE => 'stashing',
|
||||
FILTER => undef,
|
||||
},
|
||||
'reset_head' => {
|
||||
DIFF => 'diff-index -p --cached',
|
||||
APPLY => sub { apply_patch 'apply -R --cached', @_; },
|
||||
APPLY_CHECK => 'apply -R --cached',
|
||||
VERB => 'Unstage',
|
||||
TARGET => '',
|
||||
PARTICIPLE => 'unstaging',
|
||||
FILTER => 'index-only',
|
||||
},
|
||||
'reset_nothead' => {
|
||||
DIFF => 'diff-index -R -p --cached',
|
||||
APPLY => sub { apply_patch 'apply --cached', @_; },
|
||||
APPLY_CHECK => 'apply --cached',
|
||||
VERB => 'Apply',
|
||||
TARGET => ' to index',
|
||||
PARTICIPLE => 'applying',
|
||||
FILTER => 'index-only',
|
||||
},
|
||||
'checkout_index' => {
|
||||
DIFF => 'diff-files -p',
|
||||
APPLY => sub { apply_patch 'apply -R', @_; },
|
||||
APPLY_CHECK => 'apply -R',
|
||||
VERB => 'Discard',
|
||||
TARGET => ' from worktree',
|
||||
PARTICIPLE => 'discarding',
|
||||
FILTER => 'file-only',
|
||||
},
|
||||
'checkout_head' => {
|
||||
DIFF => 'diff-index -p',
|
||||
APPLY => sub { apply_patch_for_checkout_commit '-R', @_ },
|
||||
APPLY_CHECK => 'apply -R',
|
||||
VERB => 'Discard',
|
||||
TARGET => ' from index and worktree',
|
||||
PARTICIPLE => 'discarding',
|
||||
FILTER => undef,
|
||||
},
|
||||
'checkout_nothead' => {
|
||||
DIFF => 'diff-index -R -p',
|
||||
APPLY => sub { apply_patch_for_checkout_commit '', @_ },
|
||||
APPLY_CHECK => 'apply',
|
||||
VERB => 'Apply',
|
||||
TARGET => ' to index and worktree',
|
||||
PARTICIPLE => 'applying',
|
||||
FILTER => undef,
|
||||
},
|
||||
);
|
||||
|
||||
my %patch_mode_flavour = %{$patch_modes{stage}};
|
||||
|
||||
sub run_cmd_pipe {
|
||||
if ($^O eq 'MSWin32' || $^O eq 'msys') {
|
||||
@@ -190,7 +263,14 @@ sub list_modified {
|
||||
return if (!@tracked);
|
||||
}
|
||||
|
||||
my $reference = is_initial_commit() ? get_empty_tree() : 'HEAD';
|
||||
my $reference;
|
||||
if (defined $patch_mode_revision and $patch_mode_revision ne 'HEAD') {
|
||||
$reference = $patch_mode_revision;
|
||||
} elsif (is_initial_commit()) {
|
||||
$reference = get_empty_tree();
|
||||
} else {
|
||||
$reference = 'HEAD';
|
||||
}
|
||||
for (run_cmd_pipe(qw(git diff-index --cached
|
||||
--numstat --summary), $reference,
|
||||
'--', @tracked)) {
|
||||
@@ -613,12 +693,24 @@ sub add_untracked_cmd {
|
||||
print "\n";
|
||||
}
|
||||
|
||||
sub run_git_apply {
|
||||
my $cmd = shift;
|
||||
my $fh;
|
||||
open $fh, '| git ' . $cmd;
|
||||
print $fh @_;
|
||||
return close $fh;
|
||||
}
|
||||
|
||||
sub parse_diff {
|
||||
my ($path) = @_;
|
||||
my @diff = run_cmd_pipe(qw(git diff-files -p --), $path);
|
||||
my @diff_cmd = split(" ", $patch_mode_flavour{DIFF});
|
||||
if (defined $patch_mode_revision) {
|
||||
push @diff_cmd, $patch_mode_revision;
|
||||
}
|
||||
my @diff = run_cmd_pipe("git", @diff_cmd, "--", $path);
|
||||
my @colored = ();
|
||||
if ($diff_use_color) {
|
||||
@colored = run_cmd_pipe(qw(git diff-files -p --color --), $path);
|
||||
@colored = run_cmd_pipe("git", @diff_cmd, qw(--color --), $path);
|
||||
}
|
||||
my (@hunk) = { TEXT => [], DISPLAY => [], TYPE => 'header' };
|
||||
|
||||
@@ -881,6 +973,7 @@ sub edit_hunk_manually {
|
||||
or die "failed to open hunk edit file for writing: " . $!;
|
||||
print $fh "# Manual hunk edit mode -- see bottom for a quick guide\n";
|
||||
print $fh @$oldtext;
|
||||
my $participle = $patch_mode_flavour{PARTICIPLE};
|
||||
print $fh <<EOF;
|
||||
# ---
|
||||
# To remove '-' lines, make them ' ' lines (context).
|
||||
@@ -888,7 +981,7 @@ sub edit_hunk_manually {
|
||||
# Lines starting with # will be removed.
|
||||
#
|
||||
# If the patch applies cleanly, the edited hunk will immediately be
|
||||
# marked for staging. If it does not apply cleanly, you will be given
|
||||
# marked for $participle. If it does not apply cleanly, you will be given
|
||||
# an opportunity to edit again. If all lines of the hunk are removed,
|
||||
# then the edit is aborted and the hunk is left unchanged.
|
||||
EOF
|
||||
@@ -922,11 +1015,8 @@ EOF
|
||||
|
||||
sub diff_applies {
|
||||
my $fh;
|
||||
open $fh, '| git apply --recount --cached --check';
|
||||
for my $h (@_) {
|
||||
print $fh @{$h->{TEXT}};
|
||||
}
|
||||
return close $fh;
|
||||
return run_git_apply($patch_mode_flavour{APPLY_CHECK} . ' --recount --check',
|
||||
map { @{$_->{TEXT}} } @_);
|
||||
}
|
||||
|
||||
sub _restore_terminal_and_die {
|
||||
@@ -992,12 +1082,14 @@ sub edit_hunk_loop {
|
||||
}
|
||||
|
||||
sub help_patch_cmd {
|
||||
print colored $help_color, <<\EOF ;
|
||||
y - stage this hunk
|
||||
n - do not stage this hunk
|
||||
q - quit, do not stage this hunk nor any of the remaining ones
|
||||
a - stage this and all the remaining hunks in the file
|
||||
d - do not stage this hunk nor any of the remaining hunks in the file
|
||||
my $verb = lc $patch_mode_flavour{VERB};
|
||||
my $target = $patch_mode_flavour{TARGET};
|
||||
print colored $help_color, <<EOF ;
|
||||
y - $verb this hunk$target
|
||||
n - do not $verb this hunk$target
|
||||
q - quit, do not $verb this hunk nor any of the remaining ones
|
||||
a - $verb this and all the remaining hunks in the file
|
||||
d - do not $verb this hunk nor any of the remaining hunks in the file
|
||||
g - select a hunk to go to
|
||||
/ - search for a hunk matching the given regex
|
||||
j - leave this hunk undecided, see next undecided hunk
|
||||
@@ -1010,8 +1102,40 @@ e - manually edit the current hunk
|
||||
EOF
|
||||
}
|
||||
|
||||
sub apply_patch {
|
||||
my $cmd = shift;
|
||||
my $ret = run_git_apply $cmd . ' --recount', @_;
|
||||
if (!$ret) {
|
||||
print STDERR @_;
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
sub apply_patch_for_checkout_commit {
|
||||
my $reverse = shift;
|
||||
my $applies_index = run_git_apply 'apply '.$reverse.' --cached --recount --check', @_;
|
||||
my $applies_worktree = run_git_apply 'apply '.$reverse.' --recount --check', @_;
|
||||
|
||||
if ($applies_worktree && $applies_index) {
|
||||
run_git_apply 'apply '.$reverse.' --cached --recount', @_;
|
||||
run_git_apply 'apply '.$reverse.' --recount', @_;
|
||||
return 1;
|
||||
} elsif (!$applies_index) {
|
||||
print colored $error_color, "The selected hunks do not apply to the index!\n";
|
||||
if (prompt_yesno "Apply them to the worktree anyway? ") {
|
||||
return run_git_apply 'apply '.$reverse.' --recount', @_;
|
||||
} else {
|
||||
print colored $error_color, "Nothing was applied.\n";
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
print STDERR @_;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
sub patch_update_cmd {
|
||||
my @all_mods = list_modified('file-only');
|
||||
my @all_mods = list_modified($patch_mode_flavour{FILTER});
|
||||
my @mods = grep { !($_->{BINARY}) } @all_mods;
|
||||
my @them;
|
||||
|
||||
@@ -1142,8 +1266,9 @@ sub patch_update_file {
|
||||
for (@{$hunk[$ix]{DISPLAY}}) {
|
||||
print;
|
||||
}
|
||||
print colored $prompt_color, 'Stage ',
|
||||
($hunk[$ix]{TYPE} eq 'mode' ? 'mode change' : 'this hunk'),
|
||||
print colored $prompt_color, $patch_mode_flavour{VERB},
|
||||
($hunk[$ix]{TYPE} eq 'mode' ? ' mode change' : ' this hunk'),
|
||||
$patch_mode_flavour{TARGET},
|
||||
" [y,n,q,a,d,/$other,?]? ";
|
||||
my $line = prompt_single_character;
|
||||
if ($line) {
|
||||
@@ -1317,16 +1442,9 @@ sub patch_update_file {
|
||||
|
||||
if (@result) {
|
||||
my $fh;
|
||||
|
||||
open $fh, '| git apply --cached --recount';
|
||||
for (@{$head->{TEXT}}, @result) {
|
||||
print $fh $_;
|
||||
}
|
||||
if (!close $fh) {
|
||||
for (@{$head->{TEXT}}, @result) {
|
||||
print STDERR $_;
|
||||
}
|
||||
}
|
||||
my @patch = (@{$head->{TEXT}}, @result);
|
||||
my $apply_routine = $patch_mode_flavour{APPLY};
|
||||
&$apply_routine(@patch);
|
||||
refresh();
|
||||
}
|
||||
|
||||
@@ -1367,11 +1485,41 @@ EOF
|
||||
sub process_args {
|
||||
return unless @ARGV;
|
||||
my $arg = shift @ARGV;
|
||||
if ($arg eq "--patch") {
|
||||
$patch_mode = 1;
|
||||
$arg = shift @ARGV or die "missing --";
|
||||
if ($arg =~ /--patch(?:=(.*))?/) {
|
||||
if (defined $1) {
|
||||
if ($1 eq 'reset') {
|
||||
$patch_mode = 'reset_head';
|
||||
$patch_mode_revision = 'HEAD';
|
||||
$arg = shift @ARGV or die "missing --";
|
||||
if ($arg ne '--') {
|
||||
$patch_mode_revision = $arg;
|
||||
$patch_mode = ($arg eq 'HEAD' ?
|
||||
'reset_head' : 'reset_nothead');
|
||||
$arg = shift @ARGV or die "missing --";
|
||||
}
|
||||
} elsif ($1 eq 'checkout') {
|
||||
$arg = shift @ARGV or die "missing --";
|
||||
if ($arg eq '--') {
|
||||
$patch_mode = 'checkout_index';
|
||||
} else {
|
||||
$patch_mode_revision = $arg;
|
||||
$patch_mode = ($arg eq 'HEAD' ?
|
||||
'checkout_head' : 'checkout_nothead');
|
||||
$arg = shift @ARGV or die "missing --";
|
||||
}
|
||||
} elsif ($1 eq 'stage' or $1 eq 'stash') {
|
||||
$patch_mode = $1;
|
||||
$arg = shift @ARGV or die "missing --";
|
||||
} else {
|
||||
die "unknown --patch mode: $1";
|
||||
}
|
||||
} else {
|
||||
$patch_mode = 'stage';
|
||||
$arg = shift @ARGV or die "missing --";
|
||||
}
|
||||
die "invalid argument $arg, expecting --"
|
||||
unless $arg eq "--";
|
||||
%patch_mode_flavour = %{$patch_modes{$patch_mode}};
|
||||
}
|
||||
elsif ($arg ne "--") {
|
||||
die "invalid argument $arg, expecting --";
|
||||
|
||||
23
git-am.sh
23
git-am.sh
@@ -15,6 +15,7 @@ q,quiet be quiet
|
||||
s,signoff add a Signed-off-by line to the commit message
|
||||
u,utf8 recode into utf8 (default)
|
||||
k,keep pass -k flag to git-mailinfo
|
||||
c,scissors strip everything before a scissors line
|
||||
whitespace= pass it through git-apply
|
||||
ignore-space-change pass it through git-apply
|
||||
ignore-whitespace pass it through git-apply
|
||||
@@ -288,7 +289,7 @@ split_patches () {
|
||||
prec=4
|
||||
dotest="$GIT_DIR/rebase-apply"
|
||||
sign= utf8=t keep= skip= interactive= resolved= rebasing= abort=
|
||||
resolvemsg= resume=
|
||||
resolvemsg= resume= scissors=
|
||||
git_apply_opt=
|
||||
committer_date_is_author_date=
|
||||
ignore_date=
|
||||
@@ -310,6 +311,10 @@ do
|
||||
utf8= ;;
|
||||
-k|--keep)
|
||||
keep=t ;;
|
||||
-c|--scissors)
|
||||
scissors=t ;;
|
||||
--no-scissors)
|
||||
scissors=f ;;
|
||||
-r|--resolved)
|
||||
resolved=t ;;
|
||||
--skip)
|
||||
@@ -317,7 +322,7 @@ do
|
||||
--abort)
|
||||
abort=t ;;
|
||||
--rebasing)
|
||||
rebasing=t threeway=t keep=t ;;
|
||||
rebasing=t threeway=t keep=t scissors=f ;;
|
||||
-d|--dotest)
|
||||
die "-d option is no longer supported. Do not use."
|
||||
;;
|
||||
@@ -435,14 +440,14 @@ else
|
||||
|
||||
split_patches "$@"
|
||||
|
||||
# -s, -u, -k, --whitespace, -3, -C, -q and -p flags are kept
|
||||
# for the resuming session after a patch failure.
|
||||
# -i can and must be given when resuming.
|
||||
# -i can and must be given when resuming; everything
|
||||
# else is kept
|
||||
echo " $git_apply_opt" >"$dotest/apply-opt"
|
||||
echo "$threeway" >"$dotest/threeway"
|
||||
echo "$sign" >"$dotest/sign"
|
||||
echo "$utf8" >"$dotest/utf8"
|
||||
echo "$keep" >"$dotest/keep"
|
||||
echo "$scissors" >"$dotest/scissors"
|
||||
echo "$GIT_QUIET" >"$dotest/quiet"
|
||||
echo 1 >"$dotest/next"
|
||||
if test -n "$rebasing"
|
||||
@@ -484,6 +489,12 @@ if test "$(cat "$dotest/keep")" = t
|
||||
then
|
||||
keep=-k
|
||||
fi
|
||||
case "$(cat "$dotest/scissors")" in
|
||||
t)
|
||||
scissors=--scissors ;;
|
||||
f)
|
||||
scissors=--no-scissors ;;
|
||||
esac
|
||||
if test "$(cat "$dotest/quiet")" = t
|
||||
then
|
||||
GIT_QUIET=t
|
||||
@@ -538,7 +549,7 @@ do
|
||||
# by the user, or the user can tell us to do so by --resolved flag.
|
||||
case "$resume" in
|
||||
'')
|
||||
git mailinfo $keep $utf8 "$dotest/msg" "$dotest/patch" \
|
||||
git mailinfo $keep $scissors $utf8 "$dotest/msg" "$dotest/patch" \
|
||||
<"$dotest/$msgnum" >"$dotest/info" ||
|
||||
stop_here $this
|
||||
|
||||
|
||||
@@ -405,7 +405,7 @@ bisect_run () {
|
||||
exit $res
|
||||
fi
|
||||
|
||||
if grep "is first bad commit" "$GIT_DIR/BISECT_RUN" > /dev/null; then
|
||||
if grep "is the first bad commit" "$GIT_DIR/BISECT_RUN" > /dev/null; then
|
||||
echo "bisect run success"
|
||||
exit 0;
|
||||
fi
|
||||
|
||||
@@ -174,6 +174,8 @@ extern char *gitbasename(char *);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "compat/bswap.h"
|
||||
|
||||
/* General helper functions */
|
||||
extern void usage(const char *err) NORETURN;
|
||||
extern void die(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2)));
|
||||
|
||||
@@ -238,7 +238,9 @@ sub conn {
|
||||
}
|
||||
my $rr = ":pserver:$user\@$serv:$port$repo";
|
||||
|
||||
unless ($pass) {
|
||||
if ($pass) {
|
||||
$pass = $self->_scramble($pass);
|
||||
} else {
|
||||
open(H,$ENV{'HOME'}."/.cvspass") and do {
|
||||
# :pserver:cvs@mea.tmt.tele.fi:/cvsroot/zmailer Ah<Z
|
||||
while (<H>) {
|
||||
@@ -253,8 +255,6 @@ sub conn {
|
||||
};
|
||||
}
|
||||
|
||||
$pass = $self->_scramble($pass);
|
||||
|
||||
my ($s, $rep);
|
||||
if ($proxyhost) {
|
||||
|
||||
|
||||
@@ -285,7 +285,7 @@ sub req_Root
|
||||
return 0;
|
||||
}
|
||||
|
||||
my @gitvars = `git-config -l`;
|
||||
my @gitvars = `git config -l`;
|
||||
if ($?) {
|
||||
print "E problems executing git-config on the server -- this is not a git repository or the PATH is not set correctly.\n";
|
||||
print "E \n";
|
||||
@@ -702,7 +702,7 @@ sub req_Modified
|
||||
# Save the file data in $state
|
||||
$state->{entries}{$state->{directory}.$data}{modified_filename} = $filename;
|
||||
$state->{entries}{$state->{directory}.$data}{modified_mode} = $mode;
|
||||
$state->{entries}{$state->{directory}.$data}{modified_hash} = `git-hash-object $filename`;
|
||||
$state->{entries}{$state->{directory}.$data}{modified_hash} = `git hash-object $filename`;
|
||||
$state->{entries}{$state->{directory}.$data}{modified_hash} =~ s/\s.*$//s;
|
||||
|
||||
#$log->debug("req_Modified : file=$data mode=$mode size=$size");
|
||||
@@ -1289,7 +1289,7 @@ sub req_ci
|
||||
|
||||
# do a checkout of the file if it is part of this tree
|
||||
if ($wrev) {
|
||||
system('git-checkout-index', '-f', '-u', $filename);
|
||||
system('git', 'checkout-index', '-f', '-u', $filename);
|
||||
unless ($? == 0) {
|
||||
die "Error running git-checkout-index -f -u $filename : $!";
|
||||
}
|
||||
@@ -1331,15 +1331,15 @@ sub req_ci
|
||||
{
|
||||
$log->info("Removing file '$filename'");
|
||||
unlink($filename);
|
||||
system("git-update-index", "--remove", $filename);
|
||||
system("git", "update-index", "--remove", $filename);
|
||||
}
|
||||
elsif ( $addflag )
|
||||
{
|
||||
$log->info("Adding file '$filename'");
|
||||
system("git-update-index", "--add", $filename);
|
||||
system("git", "update-index", "--add", $filename);
|
||||
} else {
|
||||
$log->info("Updating file '$filename'");
|
||||
system("git-update-index", $filename);
|
||||
system("git", "update-index", $filename);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1351,7 +1351,7 @@ sub req_ci
|
||||
return;
|
||||
}
|
||||
|
||||
my $treehash = `git-write-tree`;
|
||||
my $treehash = `git write-tree`;
|
||||
chomp $treehash;
|
||||
|
||||
$log->debug("Treehash : $treehash, Parenthash : $parenthash");
|
||||
@@ -1368,7 +1368,7 @@ sub req_ci
|
||||
}
|
||||
close $msg_fh;
|
||||
|
||||
my $commithash = `git-commit-tree $treehash -p $parenthash < $msg_filename`;
|
||||
my $commithash = `git commit-tree $treehash -p $parenthash < $msg_filename`;
|
||||
chomp($commithash);
|
||||
$log->info("Commit hash : $commithash");
|
||||
|
||||
@@ -1821,7 +1821,7 @@ sub req_annotate
|
||||
# TODO: if we got a revision from the client, use that instead
|
||||
# to look up the commithash in sqlite (still good to default to
|
||||
# the current head as we do now)
|
||||
system("git-read-tree", $lastseenin);
|
||||
system("git", "read-tree", $lastseenin);
|
||||
unless ($? == 0)
|
||||
{
|
||||
print "E error running git-read-tree $lastseenin $ENV{GIT_INDEX_FILE} $!\n";
|
||||
@@ -1830,7 +1830,7 @@ sub req_annotate
|
||||
$log->info("Created index '$ENV{GIT_INDEX_FILE}' with commit $lastseenin - exit status $?");
|
||||
|
||||
# do a checkout of the file
|
||||
system('git-checkout-index', '-f', '-u', $filename);
|
||||
system('git', 'checkout-index', '-f', '-u', $filename);
|
||||
unless ($? == 0) {
|
||||
print "E error running git-checkout-index -f -u $filename : $!\n";
|
||||
return;
|
||||
@@ -1861,7 +1861,7 @@ sub req_annotate
|
||||
close ANNOTATEHINTS
|
||||
or (print "E failed to write $a_hints: $!\n"), return;
|
||||
|
||||
my @cmd = (qw(git-annotate -l -S), $a_hints, $filename);
|
||||
my @cmd = (qw(git annotate -l -S), $a_hints, $filename);
|
||||
if (!open(ANNOTATE, "-|", @cmd)) {
|
||||
print "E error invoking ". join(' ',@cmd) .": $!\n";
|
||||
return;
|
||||
@@ -2078,17 +2078,17 @@ sub transmitfile
|
||||
|
||||
die "Need filehash" unless ( defined ( $filehash ) and $filehash =~ /^[a-zA-Z0-9]{40}$/ );
|
||||
|
||||
my $type = `git-cat-file -t $filehash`;
|
||||
my $type = `git cat-file -t $filehash`;
|
||||
chomp $type;
|
||||
|
||||
die ( "Invalid type '$type' (expected 'blob')" ) unless ( defined ( $type ) and $type eq "blob" );
|
||||
|
||||
my $size = `git-cat-file -s $filehash`;
|
||||
my $size = `git cat-file -s $filehash`;
|
||||
chomp $size;
|
||||
|
||||
$log->debug("transmitfile($filehash) size=$size, type=$type");
|
||||
|
||||
if ( open my $fh, '-|', "git-cat-file", "blob", $filehash )
|
||||
if ( open my $fh, '-|', "git", "cat-file", "blob", $filehash )
|
||||
{
|
||||
if ( defined ( $options->{targetfile} ) )
|
||||
{
|
||||
@@ -2935,7 +2935,7 @@ sub update
|
||||
push @git_log_params, $self->{module};
|
||||
}
|
||||
# git-rev-list is the backend / plumbing version of git-log
|
||||
open(GITLOG, '-|', 'git-rev-list', @git_log_params) or die "Cannot call git-rev-list: $!";
|
||||
open(GITLOG, '-|', 'git', 'rev-list', @git_log_params) or die "Cannot call git-rev-list: $!";
|
||||
|
||||
my @commits;
|
||||
|
||||
@@ -3021,7 +3021,7 @@ sub update
|
||||
next;
|
||||
}
|
||||
my $base = eval {
|
||||
safe_pipe_capture('git-merge-base',
|
||||
safe_pipe_capture('git', 'merge-base',
|
||||
$lastpicked, $parent);
|
||||
};
|
||||
# The two branches may not be related at all,
|
||||
@@ -3033,7 +3033,7 @@ sub update
|
||||
if ($base) {
|
||||
my @merged;
|
||||
# print "want to log between $base $parent \n";
|
||||
open(GITLOG, '-|', 'git-log', '--pretty=medium', "$base..$parent")
|
||||
open(GITLOG, '-|', 'git', 'log', '--pretty=medium', "$base..$parent")
|
||||
or die "Cannot call git-log: $!";
|
||||
my $mergedhash;
|
||||
while (<GITLOG>) {
|
||||
@@ -3075,7 +3075,7 @@ sub update
|
||||
|
||||
if ( defined ( $lastpicked ) )
|
||||
{
|
||||
my $filepipe = open(FILELIST, '-|', 'git-diff-tree', '-z', '-r', $lastpicked, $commit->{hash}) or die("Cannot call git-diff-tree : $!");
|
||||
my $filepipe = open(FILELIST, '-|', 'git', 'diff-tree', '-z', '-r', $lastpicked, $commit->{hash}) or die("Cannot call git-diff-tree : $!");
|
||||
local ($/) = "\0";
|
||||
while ( <FILELIST> )
|
||||
{
|
||||
@@ -3149,7 +3149,7 @@ sub update
|
||||
# this is used to detect files removed from the repo
|
||||
my $seen_files = {};
|
||||
|
||||
my $filepipe = open(FILELIST, '-|', 'git-ls-tree', '-z', '-r', $commit->{hash}) or die("Cannot call git-ls-tree : $!");
|
||||
my $filepipe = open(FILELIST, '-|', 'git', 'ls-tree', '-z', '-r', $commit->{hash}) or die("Cannot call git-ls-tree : $!");
|
||||
local $/ = "\0";
|
||||
while ( <FILELIST> )
|
||||
{
|
||||
@@ -3451,7 +3451,7 @@ sub commitmessage
|
||||
return $message;
|
||||
}
|
||||
|
||||
my @lines = safe_pipe_capture("git-cat-file", "commit", $commithash);
|
||||
my @lines = safe_pipe_capture("git", "cat-file", "commit", $commithash);
|
||||
shift @lines while ( $lines[0] =~ /\S/ );
|
||||
$message = join("",@lines);
|
||||
$message .= " " if ( $message =~ /\n$/ );
|
||||
|
||||
@@ -77,11 +77,30 @@ start_httpd () {
|
||||
resolve_full_httpd
|
||||
|
||||
# don't quote $full_httpd, there can be arguments to it (-f)
|
||||
$full_httpd "$fqgitdir/gitweb/httpd.conf"
|
||||
if test $? != 0; then
|
||||
echo "Could not execute http daemon $httpd."
|
||||
exit 1
|
||||
fi
|
||||
case "$httpd" in
|
||||
*mongoose*)
|
||||
#The mongoose server doesn't have a daemon mode so we'll have to fork it
|
||||
$full_httpd "$fqgitdir/gitweb/httpd.conf" &
|
||||
#Save the pid before doing anything else (we'll print it later)
|
||||
pid=$!
|
||||
|
||||
if test $? != 0; then
|
||||
echo "Could not execute http daemon $httpd."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cat > "$fqgitdir/pid" <<EOF
|
||||
$pid
|
||||
EOF
|
||||
;;
|
||||
*)
|
||||
$full_httpd "$fqgitdir/gitweb/httpd.conf"
|
||||
if test $? != 0; then
|
||||
echo "Could not execute http daemon $httpd."
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
stop_httpd () {
|
||||
@@ -308,6 +327,31 @@ EOF
|
||||
fi
|
||||
}
|
||||
|
||||
mongoose_conf() {
|
||||
cat > "$conf" <<EOF
|
||||
# Mongoose web server configuration file.
|
||||
# Lines starting with '#' and empty lines are ignored.
|
||||
# For detailed description of every option, visit
|
||||
# http://code.google.com/p/mongoose/wiki/MongooseManual
|
||||
|
||||
root $fqgitdir/gitweb
|
||||
ports $port
|
||||
index_files gitweb.cgi
|
||||
#ssl_cert $fqgitdir/gitweb/ssl_cert.pem
|
||||
error_log $fqgitdir/gitweb/error.log
|
||||
access_log $fqgitdir/gitweb/access.log
|
||||
|
||||
#cgi setup
|
||||
cgi_env PATH=/usr/local/bin:/usr/bin:/bin,GIT_DIR=$GIT_DIR,GIT_EXEC_PATH=$GIT_EXEC_PATH
|
||||
cgi_interp $PERL
|
||||
cgi_ext cgi,pl
|
||||
|
||||
# mimetype mapping
|
||||
mime_types .gz=application/x-gzip,.tar.gz=application/x-tgz,.tgz=application/x-tgz,.tar=application/x-tar,.zip=application/zip,.gif=image/gif,.jpg=image/jpeg,.jpeg=image/jpeg,.png=image/png,.css=text/css,.html=text/html,.htm=text/html,.js=text/javascript,.c=text/plain,.cpp=text/plain,.log=text/plain,.conf=text/plain,.text=text/plain,.txt=text/plain,.dtd=text/xml,.bz2=application/x-bzip,.tbz=application/x-bzip-compressed-tar,.tar.bz2=application/x-bzip-compressed-tar
|
||||
EOF
|
||||
}
|
||||
|
||||
|
||||
script='
|
||||
s#^(my|our) \$projectroot =.*#$1 \$projectroot = "'$(dirname "$fqgitdir")'";#;
|
||||
s#(my|our) \$gitbin =.*#$1 \$gitbin = "'$GIT_EXEC_PATH'";#;
|
||||
@@ -344,6 +388,9 @@ case "$httpd" in
|
||||
webrick)
|
||||
webrick_conf
|
||||
;;
|
||||
*mongoose*)
|
||||
mongoose_conf
|
||||
;;
|
||||
*)
|
||||
echo "Unknown httpd specified: $httpd"
|
||||
exit 1
|
||||
|
||||
140
git-stash.sh
140
git-stash.sh
@@ -7,7 +7,7 @@ USAGE="list [<options>]
|
||||
or: $dashless drop [-q|--quiet] [<stash>]
|
||||
or: $dashless ( pop | apply ) [--index] [-q|--quiet] [<stash>]
|
||||
or: $dashless branch <branchname> [<stash>]
|
||||
or: $dashless [save [--keep-index] [-q|--quiet] [<message>]]
|
||||
or: $dashless [save [-k|--keep-index] [-q|--quiet] [<message>]]
|
||||
or: $dashless clear"
|
||||
|
||||
SUBDIRECTORY_OK=Yes
|
||||
@@ -21,6 +21,14 @@ trap 'rm -f "$TMP-*"' 0
|
||||
|
||||
ref_stash=refs/stash
|
||||
|
||||
if git config --get-colorbool color.interactive; then
|
||||
help_color="$(git config --get-color color.interactive.help 'red bold')"
|
||||
reset_color="$(git config --get-color '' reset)"
|
||||
else
|
||||
help_color=
|
||||
reset_color=
|
||||
fi
|
||||
|
||||
no_changes () {
|
||||
git diff-index --quiet --cached HEAD --ignore-submodules -- &&
|
||||
git diff-files --quiet --ignore-submodules
|
||||
@@ -68,19 +76,44 @@ create_stash () {
|
||||
git commit-tree $i_tree -p $b_commit) ||
|
||||
die "Cannot save the current index state"
|
||||
|
||||
# state of the working tree
|
||||
w_tree=$( (
|
||||
if test -z "$patch_mode"
|
||||
then
|
||||
|
||||
# state of the working tree
|
||||
w_tree=$( (
|
||||
rm -f "$TMP-index" &&
|
||||
cp -p ${GIT_INDEX_FILE-"$GIT_DIR/index"} "$TMP-index" &&
|
||||
GIT_INDEX_FILE="$TMP-index" &&
|
||||
export GIT_INDEX_FILE &&
|
||||
git read-tree -m $i_tree &&
|
||||
git add -u &&
|
||||
git write-tree &&
|
||||
rm -f "$TMP-index"
|
||||
) ) ||
|
||||
die "Cannot save the current worktree state"
|
||||
|
||||
else
|
||||
|
||||
rm -f "$TMP-index" &&
|
||||
cp -p ${GIT_INDEX_FILE-"$GIT_DIR/index"} "$TMP-index" &&
|
||||
GIT_INDEX_FILE="$TMP-index" &&
|
||||
export GIT_INDEX_FILE &&
|
||||
git read-tree -m $i_tree &&
|
||||
git add -u &&
|
||||
git write-tree &&
|
||||
rm -f "$TMP-index"
|
||||
) ) ||
|
||||
GIT_INDEX_FILE="$TMP-index" git read-tree HEAD &&
|
||||
|
||||
# find out what the user wants
|
||||
GIT_INDEX_FILE="$TMP-index" \
|
||||
git add--interactive --patch=stash -- &&
|
||||
|
||||
# state of the working tree
|
||||
w_tree=$(GIT_INDEX_FILE="$TMP-index" git write-tree) ||
|
||||
die "Cannot save the current worktree state"
|
||||
|
||||
git diff-tree -p HEAD $w_tree > "$TMP-patch" &&
|
||||
test -s "$TMP-patch" ||
|
||||
die "No changes selected"
|
||||
|
||||
rm -f "$TMP-index" ||
|
||||
die "Cannot remove temporary index (can't happen)"
|
||||
|
||||
fi
|
||||
|
||||
# create the stash
|
||||
if test -z "$stash_msg"
|
||||
then
|
||||
@@ -95,15 +128,31 @@ create_stash () {
|
||||
|
||||
save_stash () {
|
||||
keep_index=
|
||||
patch_mode=
|
||||
while test $# != 0
|
||||
do
|
||||
case "$1" in
|
||||
--keep-index)
|
||||
-k|--keep-index)
|
||||
keep_index=t
|
||||
;;
|
||||
--no-keep-index)
|
||||
keep_index=
|
||||
;;
|
||||
-p|--patch)
|
||||
patch_mode=t
|
||||
keep_index=t
|
||||
;;
|
||||
-q|--quiet)
|
||||
GIT_QUIET=t
|
||||
;;
|
||||
--)
|
||||
shift
|
||||
break
|
||||
;;
|
||||
-*)
|
||||
echo "error: unknown option for 'stash save': $1"
|
||||
usage
|
||||
;;
|
||||
*)
|
||||
break
|
||||
;;
|
||||
@@ -131,11 +180,22 @@ save_stash () {
|
||||
die "Cannot save the current status"
|
||||
say Saved working directory and index state "$stash_msg"
|
||||
|
||||
git reset --hard ${GIT_QUIET:+-q}
|
||||
|
||||
if test -n "$keep_index" && test -n $i_tree
|
||||
if test -z "$patch_mode"
|
||||
then
|
||||
git read-tree --reset -u $i_tree
|
||||
git reset --hard ${GIT_QUIET:+-q}
|
||||
|
||||
if test -n "$keep_index" && test -n $i_tree
|
||||
then
|
||||
git read-tree --reset -u $i_tree
|
||||
fi
|
||||
else
|
||||
git apply -R < "$TMP-patch" ||
|
||||
die "Cannot remove worktree changes"
|
||||
|
||||
if test -z "$keep_index"
|
||||
then
|
||||
git reset
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -162,10 +222,6 @@ show_stash () {
|
||||
}
|
||||
|
||||
apply_stash () {
|
||||
git update-index -q --refresh &&
|
||||
git diff-files --quiet --ignore-submodules ||
|
||||
die 'Cannot apply to a dirty working tree, please stage your changes'
|
||||
|
||||
unstash_index=
|
||||
|
||||
while test $# != 0
|
||||
@@ -184,18 +240,27 @@ apply_stash () {
|
||||
shift
|
||||
done
|
||||
|
||||
# current index state
|
||||
c_tree=$(git write-tree) ||
|
||||
die 'Cannot apply a stash in the middle of a merge'
|
||||
if test $# = 0
|
||||
then
|
||||
have_stash || die 'Nothing to apply'
|
||||
fi
|
||||
|
||||
# stash records the work tree, and is a merge between the
|
||||
# base commit (first parent) and the index tree (second parent).
|
||||
s=$(git rev-parse --verify --default $ref_stash "$@") &&
|
||||
w_tree=$(git rev-parse --verify "$s:") &&
|
||||
b_tree=$(git rev-parse --verify "$s^1:") &&
|
||||
i_tree=$(git rev-parse --verify "$s^2:") ||
|
||||
s=$(git rev-parse --quiet --verify --default $ref_stash "$@") &&
|
||||
w_tree=$(git rev-parse --quiet --verify "$s:") &&
|
||||
b_tree=$(git rev-parse --quiet --verify "$s^1:") &&
|
||||
i_tree=$(git rev-parse --quiet --verify "$s^2:") ||
|
||||
die "$*: no valid stashed state found"
|
||||
|
||||
git update-index -q --refresh &&
|
||||
git diff-files --quiet --ignore-submodules ||
|
||||
die 'Cannot apply to a dirty working tree, please stage your changes'
|
||||
|
||||
# current index state
|
||||
c_tree=$(git write-tree) ||
|
||||
die 'Cannot apply a stash in the middle of a merge'
|
||||
|
||||
unstashed_index_tree=
|
||||
if test -n "$unstash_index" && test "$b_tree" != "$i_tree" &&
|
||||
test "$c_tree" != "$i_tree"
|
||||
@@ -302,6 +367,18 @@ apply_to_branch () {
|
||||
drop_stash $stash
|
||||
}
|
||||
|
||||
# The default command is "save" if nothing but options are given
|
||||
seen_non_option=
|
||||
for opt
|
||||
do
|
||||
case "$opt" in
|
||||
-*) ;;
|
||||
*) seen_non_option=t; break ;;
|
||||
esac
|
||||
done
|
||||
|
||||
test -n "$seen_non_option" || set "save" "$@"
|
||||
|
||||
# Main command set
|
||||
case "$1" in
|
||||
list)
|
||||
@@ -353,12 +430,13 @@ branch)
|
||||
apply_to_branch "$@"
|
||||
;;
|
||||
*)
|
||||
if test $# -eq 0
|
||||
then
|
||||
case $# in
|
||||
0)
|
||||
save_stash &&
|
||||
say '(To restore them type "git stash apply")'
|
||||
else
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
fi
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
@@ -4,9 +4,14 @@
|
||||
#
|
||||
# Copyright (c) 2007 Lars Hjemli
|
||||
|
||||
USAGE="[--quiet] [--cached] \
|
||||
[add [-b branch] <repo> <path>]|[status|init|update [-i|--init] [-N|--no-fetch] [--rebase|--merge]|summary [-n|--summary-limit <n>] [<commit>]] \
|
||||
[--] [<path>...]|[foreach <command>]|[sync [--] [<path>...]]"
|
||||
dashless=$(basename "$0" | sed -e 's/-/ /')
|
||||
USAGE="[--quiet] add [-b branch] [--reference <repository>] [--] <repository> <path>
|
||||
or: $dashless [--quiet] status [--cached] [--recursive] [--] [<path>...]
|
||||
or: $dashless [--quiet] init [--] [<path>...]
|
||||
or: $dashless [--quiet] update [--init] [-N|--no-fetch] [--rebase] [--reference <repository>] [--merge] [--recursive] [--] [<path>...]
|
||||
or: $dashless [--quiet] summary [--cached|--files] [--summary-limit <n>] [commit] [--] [<path>...]
|
||||
or: $dashless [--quiet] foreach [--recursive] <command>
|
||||
or: $dashless [--quiet] sync [--] [<path>...]"
|
||||
OPTIONS_SPEC=
|
||||
. git-sh-setup
|
||||
. git-parse-remote
|
||||
@@ -16,8 +21,10 @@ command=
|
||||
branch=
|
||||
reference=
|
||||
cached=
|
||||
files=
|
||||
nofetch=
|
||||
update=
|
||||
prefix=
|
||||
|
||||
# Resolve relative url by appending to parent's url
|
||||
resolve_relative_url ()
|
||||
@@ -237,13 +244,43 @@ cmd_add()
|
||||
#
|
||||
cmd_foreach()
|
||||
{
|
||||
# parse $args after "submodule ... foreach".
|
||||
while test $# -ne 0
|
||||
do
|
||||
case "$1" in
|
||||
-q|--quiet)
|
||||
GIT_QUIET=1
|
||||
;;
|
||||
--recursive)
|
||||
recursive=1
|
||||
;;
|
||||
-*)
|
||||
usage
|
||||
;;
|
||||
*)
|
||||
break
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
module_list |
|
||||
while read mode sha1 stage path
|
||||
do
|
||||
if test -e "$path"/.git
|
||||
then
|
||||
say "Entering '$path'"
|
||||
(cd "$path" && eval "$@") ||
|
||||
say "Entering '$prefix$path'"
|
||||
name=$(module_name "$path")
|
||||
(
|
||||
prefix="$prefix$path/"
|
||||
unset GIT_DIR
|
||||
cd "$path" &&
|
||||
eval "$@" &&
|
||||
if test -n "$recursive"
|
||||
then
|
||||
cmd_foreach "--recursive" "$@"
|
||||
fi
|
||||
) ||
|
||||
die "Stopping at '$path'; script returned non-zero status."
|
||||
fi
|
||||
done
|
||||
@@ -316,6 +353,7 @@ cmd_init()
|
||||
cmd_update()
|
||||
{
|
||||
# parse $args after "submodule ... update".
|
||||
orig_args="$@"
|
||||
while test $# -ne 0
|
||||
do
|
||||
case "$1" in
|
||||
@@ -348,6 +386,10 @@ cmd_update()
|
||||
shift
|
||||
update="merge"
|
||||
;;
|
||||
--recursive)
|
||||
shift
|
||||
recursive=1
|
||||
;;
|
||||
--)
|
||||
shift
|
||||
break
|
||||
@@ -434,6 +476,12 @@ cmd_update()
|
||||
die "Unable to $action '$sha1' in submodule path '$path'"
|
||||
say "Submodule path '$path': $msg '$sha1'"
|
||||
fi
|
||||
|
||||
if test -n "$recursive"
|
||||
then
|
||||
(unset GIT_DIR; cd "$path" && cmd_update $orig_args) ||
|
||||
die "Failed to recurse into submodule path '$path'"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
@@ -460,6 +508,7 @@ set_name_rev () {
|
||||
cmd_summary() {
|
||||
summary_limit=-1
|
||||
for_status=
|
||||
diff_cmd=diff-index
|
||||
|
||||
# parse $args after "submodule ... summary".
|
||||
while test $# -ne 0
|
||||
@@ -468,6 +517,9 @@ cmd_summary() {
|
||||
--cached)
|
||||
cached="$1"
|
||||
;;
|
||||
--files)
|
||||
files="$1"
|
||||
;;
|
||||
--for-status)
|
||||
for_status="$1"
|
||||
;;
|
||||
@@ -504,9 +556,17 @@ cmd_summary() {
|
||||
head=HEAD
|
||||
fi
|
||||
|
||||
if [ -n "$files" ]
|
||||
then
|
||||
test -n "$cached" &&
|
||||
die "--cached cannot be used with --files"
|
||||
diff_cmd=diff-files
|
||||
head=
|
||||
fi
|
||||
|
||||
cd_to_toplevel
|
||||
# Get modified modules cared by user
|
||||
modules=$(git diff-index $cached --raw $head -- "$@" |
|
||||
modules=$(git $diff_cmd $cached --raw $head -- "$@" |
|
||||
egrep '^:([0-7]* )?160000' |
|
||||
while read mod_src mod_dst sha1_src sha1_dst status name
|
||||
do
|
||||
@@ -520,7 +580,7 @@ cmd_summary() {
|
||||
|
||||
test -z "$modules" && return
|
||||
|
||||
git diff-index $cached --raw $head -- $modules |
|
||||
git $diff_cmd $cached --raw $head -- $modules |
|
||||
egrep '^:([0-7]* )?160000' |
|
||||
cut -c2- |
|
||||
while read mod_src mod_dst sha1_src sha1_dst status name
|
||||
@@ -643,6 +703,7 @@ cmd_summary() {
|
||||
cmd_status()
|
||||
{
|
||||
# parse $args after "submodule ... status".
|
||||
orig_args="$@"
|
||||
while test $# -ne 0
|
||||
do
|
||||
case "$1" in
|
||||
@@ -652,6 +713,9 @@ cmd_status()
|
||||
--cached)
|
||||
cached=1
|
||||
;;
|
||||
--recursive)
|
||||
recursive=1
|
||||
;;
|
||||
--)
|
||||
shift
|
||||
break
|
||||
@@ -671,22 +735,34 @@ cmd_status()
|
||||
do
|
||||
name=$(module_name "$path") || exit
|
||||
url=$(git config submodule."$name".url)
|
||||
displaypath="$prefix$path"
|
||||
if test -z "$url" || ! test -d "$path"/.git -o -f "$path"/.git
|
||||
then
|
||||
say "-$sha1 $path"
|
||||
say "-$sha1 $displaypath"
|
||||
continue;
|
||||
fi
|
||||
set_name_rev "$path" "$sha1"
|
||||
if git diff-files --quiet -- "$path"
|
||||
then
|
||||
say " $sha1 $path$revname"
|
||||
say " $sha1 $displaypath$revname"
|
||||
else
|
||||
if test -z "$cached"
|
||||
then
|
||||
sha1=$(unset GIT_DIR; cd "$path" && git rev-parse --verify HEAD)
|
||||
set_name_rev "$path" "$sha1"
|
||||
fi
|
||||
say "+$sha1 $path$revname"
|
||||
say "+$sha1 $displaypath$revname"
|
||||
fi
|
||||
|
||||
if test -n "$recursive"
|
||||
then
|
||||
(
|
||||
prefix="$displaypath/"
|
||||
unset GIT_DIR
|
||||
cd "$path" &&
|
||||
cmd_status $orig_args
|
||||
) ||
|
||||
die "Failed to recurse into submodule path '$path'"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
1
git.c
1
git.c
@@ -359,6 +359,7 @@ static void handle_internal_command(int argc, const char **argv)
|
||||
{ "unpack-objects", cmd_unpack_objects, RUN_SETUP },
|
||||
{ "update-index", cmd_update_index, RUN_SETUP },
|
||||
{ "update-ref", cmd_update_ref, RUN_SETUP },
|
||||
{ "update-server-info", cmd_update_server_info, RUN_SETUP },
|
||||
{ "upload-archive", cmd_upload_archive },
|
||||
{ "verify-tag", cmd_verify_tag, RUN_SETUP },
|
||||
{ "version", cmd_version },
|
||||
|
||||
@@ -415,7 +415,7 @@ sub gitweb_get_feature {
|
||||
@{$feature{$name}{'default'}});
|
||||
if (!$override) { return @defaults; }
|
||||
if (!defined $sub) {
|
||||
warn "feature $name is not overrideable";
|
||||
warn "feature $name is not overridable";
|
||||
return @defaults;
|
||||
}
|
||||
return $sub->(@defaults);
|
||||
@@ -5190,10 +5190,10 @@ sub git_snapshot {
|
||||
die_error(400, "Invalid snapshot format parameter");
|
||||
} elsif (!exists($known_snapshot_formats{$format})) {
|
||||
die_error(400, "Unknown snapshot format");
|
||||
} elsif (!grep($_ eq $format, @snapshot_fmts)) {
|
||||
die_error(403, "Unsupported snapshot format");
|
||||
} elsif ($known_snapshot_formats{$format}{'disabled'}) {
|
||||
die_error(403, "Snapshot format not allowed");
|
||||
} elsif (!grep($_ eq $format, @snapshot_fmts)) {
|
||||
die_error(403, "Unsupported snapshot format");
|
||||
}
|
||||
|
||||
if (!defined $hash) {
|
||||
|
||||
5
graph.c
5
graph.c
@@ -291,9 +291,10 @@ static int graph_is_interesting(struct git_graph *graph, struct commit *commit)
|
||||
}
|
||||
|
||||
/*
|
||||
* Uninteresting and pruned commits won't be printed
|
||||
* Otherwise, use get_commit_action() to see if this commit is
|
||||
* interesting
|
||||
*/
|
||||
return (commit->object.flags & (UNINTERESTING | TREESAME)) ? 0 : 1;
|
||||
return get_commit_action(graph->revs, commit) == commit_show;
|
||||
}
|
||||
|
||||
static struct commit_list *next_interesting_parent(struct git_graph *graph,
|
||||
|
||||
7
http.c
7
http.c
@@ -1289,5 +1289,10 @@ void release_http_object_request(struct http_object_request *freq)
|
||||
free(freq->url);
|
||||
freq->url = NULL;
|
||||
}
|
||||
freq->slot = NULL;
|
||||
if (freq->slot != NULL) {
|
||||
freq->slot->callback_func = NULL;
|
||||
freq->slot->callback_data = NULL;
|
||||
release_active_slot(freq->slot);
|
||||
freq->slot = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,8 @@ static int add_ref_decoration(const char *refname, const unsigned char *sha1, in
|
||||
struct object *obj = parse_object(sha1);
|
||||
if (!obj)
|
||||
return 0;
|
||||
refname = prettify_refname(refname);
|
||||
if (!cb_data || *(int *)cb_data == DECORATE_SHORT_REFS)
|
||||
refname = prettify_refname(refname);
|
||||
add_name_decoration("", refname, obj);
|
||||
while (obj->type == OBJ_TAG) {
|
||||
obj = ((struct tag *)obj)->tagged;
|
||||
@@ -36,12 +37,12 @@ static int add_ref_decoration(const char *refname, const unsigned char *sha1, in
|
||||
return 0;
|
||||
}
|
||||
|
||||
void load_ref_decorations(void)
|
||||
void load_ref_decorations(int flags)
|
||||
{
|
||||
static int loaded;
|
||||
if (!loaded) {
|
||||
loaded = 1;
|
||||
for_each_ref(add_ref_decoration, NULL);
|
||||
for_each_ref(add_ref_decoration, &flags);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ void log_write_email_headers(struct rev_info *opt, struct commit *commit,
|
||||
const char **subject_p,
|
||||
const char **extra_headers_p,
|
||||
int *need_8bit_cte_p);
|
||||
void load_ref_decorations(void);
|
||||
void load_ref_decorations(int flags);
|
||||
|
||||
#define FORMAT_PATCH_NAME_MAX 64
|
||||
void get_patch_filename(struct commit *commit, int nr, const char *suffix,
|
||||
|
||||
@@ -1,151 +0,0 @@
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is SHA 180-1 Reference Implementation (Compact version)
|
||||
*
|
||||
* The Initial Developer of the Original Code is Paul Kocher of
|
||||
* Cryptography Research. Portions created by Paul Kocher are
|
||||
* Copyright (C) 1995-9 by Cryptography Research, Inc. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Paul Kocher
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
|
||||
#include "sha1.h"
|
||||
|
||||
static void shaHashBlock(moz_SHA_CTX *ctx);
|
||||
|
||||
void moz_SHA1_Init(moz_SHA_CTX *ctx) {
|
||||
int i;
|
||||
|
||||
ctx->lenW = 0;
|
||||
ctx->sizeHi = ctx->sizeLo = 0;
|
||||
|
||||
/* Initialize H with the magic constants (see FIPS180 for constants)
|
||||
*/
|
||||
ctx->H[0] = 0x67452301;
|
||||
ctx->H[1] = 0xefcdab89;
|
||||
ctx->H[2] = 0x98badcfe;
|
||||
ctx->H[3] = 0x10325476;
|
||||
ctx->H[4] = 0xc3d2e1f0;
|
||||
|
||||
for (i = 0; i < 80; i++)
|
||||
ctx->W[i] = 0;
|
||||
}
|
||||
|
||||
|
||||
void moz_SHA1_Update(moz_SHA_CTX *ctx, const void *_dataIn, int len) {
|
||||
const unsigned char *dataIn = _dataIn;
|
||||
int i;
|
||||
|
||||
/* Read the data into W and process blocks as they get full
|
||||
*/
|
||||
for (i = 0; i < len; i++) {
|
||||
ctx->W[ctx->lenW / 4] <<= 8;
|
||||
ctx->W[ctx->lenW / 4] |= (unsigned int)dataIn[i];
|
||||
if ((++ctx->lenW) % 64 == 0) {
|
||||
shaHashBlock(ctx);
|
||||
ctx->lenW = 0;
|
||||
}
|
||||
ctx->sizeLo += 8;
|
||||
ctx->sizeHi += (ctx->sizeLo < 8);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void moz_SHA1_Final(unsigned char hashout[20], moz_SHA_CTX *ctx) {
|
||||
unsigned char pad0x80 = 0x80;
|
||||
unsigned char pad0x00 = 0x00;
|
||||
unsigned char padlen[8];
|
||||
int i;
|
||||
|
||||
/* Pad with a binary 1 (e.g. 0x80), then zeroes, then length
|
||||
*/
|
||||
padlen[0] = (unsigned char)((ctx->sizeHi >> 24) & 255);
|
||||
padlen[1] = (unsigned char)((ctx->sizeHi >> 16) & 255);
|
||||
padlen[2] = (unsigned char)((ctx->sizeHi >> 8) & 255);
|
||||
padlen[3] = (unsigned char)((ctx->sizeHi >> 0) & 255);
|
||||
padlen[4] = (unsigned char)((ctx->sizeLo >> 24) & 255);
|
||||
padlen[5] = (unsigned char)((ctx->sizeLo >> 16) & 255);
|
||||
padlen[6] = (unsigned char)((ctx->sizeLo >> 8) & 255);
|
||||
padlen[7] = (unsigned char)((ctx->sizeLo >> 0) & 255);
|
||||
moz_SHA1_Update(ctx, &pad0x80, 1);
|
||||
while (ctx->lenW != 56)
|
||||
moz_SHA1_Update(ctx, &pad0x00, 1);
|
||||
moz_SHA1_Update(ctx, padlen, 8);
|
||||
|
||||
/* Output hash
|
||||
*/
|
||||
for (i = 0; i < 20; i++) {
|
||||
hashout[i] = (unsigned char)(ctx->H[i / 4] >> 24);
|
||||
ctx->H[i / 4] <<= 8;
|
||||
}
|
||||
|
||||
/*
|
||||
* Re-initialize the context (also zeroizes contents)
|
||||
*/
|
||||
moz_SHA1_Init(ctx);
|
||||
}
|
||||
|
||||
|
||||
#define SHA_ROT(X,n) (((X) << (n)) | ((X) >> (32-(n))))
|
||||
|
||||
static void shaHashBlock(moz_SHA_CTX *ctx) {
|
||||
int t;
|
||||
unsigned int A,B,C,D,E,TEMP;
|
||||
|
||||
for (t = 16; t <= 79; t++)
|
||||
ctx->W[t] =
|
||||
SHA_ROT(ctx->W[t-3] ^ ctx->W[t-8] ^ ctx->W[t-14] ^ ctx->W[t-16], 1);
|
||||
|
||||
A = ctx->H[0];
|
||||
B = ctx->H[1];
|
||||
C = ctx->H[2];
|
||||
D = ctx->H[3];
|
||||
E = ctx->H[4];
|
||||
|
||||
for (t = 0; t <= 19; t++) {
|
||||
TEMP = SHA_ROT(A,5) + (((C^D)&B)^D) + E + ctx->W[t] + 0x5a827999;
|
||||
E = D; D = C; C = SHA_ROT(B, 30); B = A; A = TEMP;
|
||||
}
|
||||
for (t = 20; t <= 39; t++) {
|
||||
TEMP = SHA_ROT(A,5) + (B^C^D) + E + ctx->W[t] + 0x6ed9eba1;
|
||||
E = D; D = C; C = SHA_ROT(B, 30); B = A; A = TEMP;
|
||||
}
|
||||
for (t = 40; t <= 59; t++) {
|
||||
TEMP = SHA_ROT(A,5) + ((B&C)|(D&(B|C))) + E + ctx->W[t] + 0x8f1bbcdc;
|
||||
E = D; D = C; C = SHA_ROT(B, 30); B = A; A = TEMP;
|
||||
}
|
||||
for (t = 60; t <= 79; t++) {
|
||||
TEMP = SHA_ROT(A,5) + (B^C^D) + E + ctx->W[t] + 0xca62c1d6;
|
||||
E = D; D = C; C = SHA_ROT(B, 30); B = A; A = TEMP;
|
||||
}
|
||||
|
||||
ctx->H[0] += A;
|
||||
ctx->H[1] += B;
|
||||
ctx->H[2] += C;
|
||||
ctx->H[3] += D;
|
||||
ctx->H[4] += E;
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is SHA 180-1 Header File
|
||||
*
|
||||
* The Initial Developer of the Original Code is Paul Kocher of
|
||||
* Cryptography Research. Portions created by Paul Kocher are
|
||||
* Copyright (C) 1995-9 by Cryptography Research, Inc. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Paul Kocher
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
unsigned int H[5];
|
||||
unsigned int W[80];
|
||||
int lenW;
|
||||
unsigned int sizeHi,sizeLo;
|
||||
} moz_SHA_CTX;
|
||||
|
||||
void moz_SHA1_Init(moz_SHA_CTX *ctx);
|
||||
void moz_SHA1_Update(moz_SHA_CTX *ctx, const void *dataIn, int len);
|
||||
void moz_SHA1_Final(unsigned char hashout[20], moz_SHA_CTX *ctx);
|
||||
|
||||
#define git_SHA_CTX moz_SHA_CTX
|
||||
#define git_SHA1_Init moz_SHA1_Init
|
||||
#define git_SHA1_Update moz_SHA1_Update
|
||||
#define git_SHA1_Final moz_SHA1_Final
|
||||
@@ -55,16 +55,15 @@ static inline struct llist_item *llist_item_get(void)
|
||||
} else {
|
||||
int i = 1;
|
||||
new = xmalloc(sizeof(struct llist_item) * BLKSIZE);
|
||||
for(;i < BLKSIZE; i++) {
|
||||
for (; i < BLKSIZE; i++)
|
||||
llist_item_put(&new[i]);
|
||||
}
|
||||
}
|
||||
return new;
|
||||
}
|
||||
|
||||
static void llist_free(struct llist *list)
|
||||
{
|
||||
while((list->back = list->front)) {
|
||||
while ((list->back = list->front)) {
|
||||
list->front = list->front->next;
|
||||
llist_item_put(list->back);
|
||||
}
|
||||
@@ -146,7 +145,7 @@ static inline struct llist_item *llist_insert_sorted_unique(struct llist *list,
|
||||
if (cmp > 0) { /* we insert before this entry */
|
||||
return llist_insert(list, prev, sha1);
|
||||
}
|
||||
if(!cmp) { /* already exists */
|
||||
if (!cmp) { /* already exists */
|
||||
return l;
|
||||
}
|
||||
prev = l;
|
||||
@@ -168,7 +167,7 @@ redo_from_start:
|
||||
int cmp = hashcmp(l->sha1, sha1);
|
||||
if (cmp > 0) /* not in list, since sorted */
|
||||
return prev;
|
||||
if(!cmp) { /* found */
|
||||
if (!cmp) { /* found */
|
||||
if (prev == NULL) {
|
||||
if (hint != NULL && hint != list->front) {
|
||||
/* we don't know the previous element */
|
||||
@@ -218,7 +217,7 @@ static inline struct pack_list * pack_list_insert(struct pack_list **pl,
|
||||
static inline size_t pack_list_size(struct pack_list *pl)
|
||||
{
|
||||
size_t ret = 0;
|
||||
while(pl) {
|
||||
while (pl) {
|
||||
ret++;
|
||||
pl = pl->next;
|
||||
}
|
||||
@@ -396,7 +395,7 @@ static size_t get_pack_redundancy(struct pack_list *pl)
|
||||
return 0;
|
||||
|
||||
while ((subset = pl->next)) {
|
||||
while(subset) {
|
||||
while (subset) {
|
||||
ret += sizeof_union(pl->pack, subset->pack);
|
||||
subset = subset->next;
|
||||
}
|
||||
@@ -427,7 +426,7 @@ static void minimize(struct pack_list **min)
|
||||
|
||||
pl = local_packs;
|
||||
while (pl) {
|
||||
if(pl->unique_objects->size)
|
||||
if (pl->unique_objects->size)
|
||||
pack_list_insert(&unique, pl);
|
||||
else
|
||||
pack_list_insert(&non_unique, pl);
|
||||
@@ -479,7 +478,7 @@ static void minimize(struct pack_list **min)
|
||||
*min = min_perm;
|
||||
/* add the unique packs to the list */
|
||||
pl = unique;
|
||||
while(pl) {
|
||||
while (pl) {
|
||||
pack_list_insert(min, pl);
|
||||
pl = pl->next;
|
||||
}
|
||||
@@ -516,7 +515,7 @@ static void cmp_local_packs(void)
|
||||
struct pack_list *subset, *pl = local_packs;
|
||||
|
||||
while ((subset = pl)) {
|
||||
while((subset = subset->next))
|
||||
while ((subset = subset->next))
|
||||
cmp_two_packs(pl, subset);
|
||||
pl = pl->next;
|
||||
}
|
||||
@@ -608,23 +607,23 @@ int main(int argc, char **argv)
|
||||
|
||||
for (i = 1; i < argc; i++) {
|
||||
const char *arg = argv[i];
|
||||
if(!strcmp(arg, "--")) {
|
||||
if (!strcmp(arg, "--")) {
|
||||
i++;
|
||||
break;
|
||||
}
|
||||
if(!strcmp(arg, "--all")) {
|
||||
if (!strcmp(arg, "--all")) {
|
||||
load_all_packs = 1;
|
||||
continue;
|
||||
}
|
||||
if(!strcmp(arg, "--verbose")) {
|
||||
if (!strcmp(arg, "--verbose")) {
|
||||
verbose = 1;
|
||||
continue;
|
||||
}
|
||||
if(!strcmp(arg, "--alt-odb")) {
|
||||
if (!strcmp(arg, "--alt-odb")) {
|
||||
alt_odb = 1;
|
||||
continue;
|
||||
}
|
||||
if(*arg == '-')
|
||||
if (*arg == '-')
|
||||
usage(pack_redundant_usage);
|
||||
else
|
||||
break;
|
||||
|
||||
2
pretty.c
2
pretty.c
@@ -583,7 +583,7 @@ static void format_decoration(struct strbuf *sb, const struct commit *commit)
|
||||
struct name_decoration *d;
|
||||
const char *prefix = " (";
|
||||
|
||||
load_ref_decorations();
|
||||
load_ref_decorations(DECORATE_SHORT_REFS);
|
||||
d = lookup_decoration(&name_decoration, &commit->object);
|
||||
while (d) {
|
||||
strbuf_addstr(sb, prefix);
|
||||
|
||||
26
read-cache.c
26
read-cache.c
@@ -1065,7 +1065,18 @@ static struct cache_entry *refresh_cache_ent(struct index_state *istate,
|
||||
return updated;
|
||||
}
|
||||
|
||||
int refresh_index(struct index_state *istate, unsigned int flags, const char **pathspec, char *seen)
|
||||
static void show_file(const char * fmt, const char * name, int in_porcelain,
|
||||
int * first, char *header_msg)
|
||||
{
|
||||
if (in_porcelain && *first && header_msg) {
|
||||
printf("%s\n", header_msg);
|
||||
*first=0;
|
||||
}
|
||||
printf(fmt, name);
|
||||
}
|
||||
|
||||
int refresh_index(struct index_state *istate, unsigned int flags, const char **pathspec,
|
||||
char *seen, char *header_msg)
|
||||
{
|
||||
int i;
|
||||
int has_errors = 0;
|
||||
@@ -1074,11 +1085,14 @@ int refresh_index(struct index_state *istate, unsigned int flags, const char **p
|
||||
int quiet = (flags & REFRESH_QUIET) != 0;
|
||||
int not_new = (flags & REFRESH_IGNORE_MISSING) != 0;
|
||||
int ignore_submodules = (flags & REFRESH_IGNORE_SUBMODULES) != 0;
|
||||
int first = 1;
|
||||
int in_porcelain = (flags & REFRESH_IN_PORCELAIN);
|
||||
unsigned int options = really ? CE_MATCH_IGNORE_VALID : 0;
|
||||
const char *needs_update_message;
|
||||
const char *needs_update_fmt;
|
||||
const char *needs_merge_fmt;
|
||||
|
||||
needs_update_message = ((flags & REFRESH_SAY_CHANGED)
|
||||
? "locally modified" : "needs update");
|
||||
needs_update_fmt = (in_porcelain ? "M\t%s\n" : "%s: needs update\n");
|
||||
needs_merge_fmt = (in_porcelain ? "U\t%s\n" : "%s: needs merge\n");
|
||||
for (i = 0; i < istate->cache_nr; i++) {
|
||||
struct cache_entry *ce, *new;
|
||||
int cache_errno = 0;
|
||||
@@ -1094,7 +1108,7 @@ int refresh_index(struct index_state *istate, unsigned int flags, const char **p
|
||||
i--;
|
||||
if (allow_unmerged)
|
||||
continue;
|
||||
printf("%s: needs merge\n", ce->name);
|
||||
show_file(needs_merge_fmt, ce->name, in_porcelain, &first, header_msg);
|
||||
has_errors = 1;
|
||||
continue;
|
||||
}
|
||||
@@ -1117,7 +1131,7 @@ int refresh_index(struct index_state *istate, unsigned int flags, const char **p
|
||||
}
|
||||
if (quiet)
|
||||
continue;
|
||||
printf("%s: %s\n", ce->name, needs_update_message);
|
||||
show_file(needs_update_fmt, ce->name, in_porcelain, &first, header_msg);
|
||||
has_errors = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
2
remote.c
2
remote.c
@@ -1038,7 +1038,7 @@ static int match_explicit(struct ref *src, struct ref *dst,
|
||||
case 0:
|
||||
if (!memcmp(dst_value, "refs/", 5))
|
||||
matched_dst = make_linked_ref(dst_value, dst_tail);
|
||||
else if((dst_guess = guess_ref(dst_value, matched_src)))
|
||||
else if ((dst_guess = guess_ref(dst_value, matched_src)))
|
||||
matched_dst = make_linked_ref(dst_guess, dst_tail);
|
||||
else
|
||||
error("unable to push to unqualified destination: %s\n"
|
||||
|
||||
19
revision.c
19
revision.c
@@ -1052,7 +1052,7 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg
|
||||
revs->simplify_by_decoration = 1;
|
||||
revs->limited = 1;
|
||||
revs->prune = 1;
|
||||
load_ref_decorations();
|
||||
load_ref_decorations(DECORATE_SHORT_REFS);
|
||||
} else if (!strcmp(arg, "--date-order")) {
|
||||
revs->lifo = 0;
|
||||
revs->topo_order = 1;
|
||||
@@ -1664,7 +1664,7 @@ static inline int want_ancestry(struct rev_info *revs)
|
||||
return (revs->rewrite_parents || revs->children.name);
|
||||
}
|
||||
|
||||
enum commit_action simplify_commit(struct rev_info *revs, struct commit *commit)
|
||||
enum commit_action get_commit_action(struct rev_info *revs, struct commit *commit)
|
||||
{
|
||||
if (commit->object.flags & SHOWN)
|
||||
return commit_ignore;
|
||||
@@ -1692,12 +1692,23 @@ enum commit_action simplify_commit(struct rev_info *revs, struct commit *commit)
|
||||
if (!commit->parents || !commit->parents->next)
|
||||
return commit_ignore;
|
||||
}
|
||||
if (want_ancestry(revs) && rewrite_parents(revs, commit) < 0)
|
||||
return commit_error;
|
||||
}
|
||||
return commit_show;
|
||||
}
|
||||
|
||||
enum commit_action simplify_commit(struct rev_info *revs, struct commit *commit)
|
||||
{
|
||||
enum commit_action action = get_commit_action(revs, commit);
|
||||
|
||||
if (action == commit_show &&
|
||||
!revs->show_all &&
|
||||
revs->prune && revs->dense && want_ancestry(revs)) {
|
||||
if (rewrite_parents(revs, commit) < 0)
|
||||
return commit_error;
|
||||
}
|
||||
return action;
|
||||
}
|
||||
|
||||
static struct commit *get_revision_1(struct rev_info *revs)
|
||||
{
|
||||
if (!revs->commits)
|
||||
|
||||
@@ -15,6 +15,9 @@
|
||||
#define SYMMETRIC_LEFT (1u<<8)
|
||||
#define ALL_REV_FLAGS ((1u<<9)-1)
|
||||
|
||||
#define DECORATE_SHORT_REFS 1
|
||||
#define DECORATE_FULL_REFS 2
|
||||
|
||||
struct rev_info;
|
||||
struct log_info;
|
||||
|
||||
@@ -165,6 +168,7 @@ enum commit_action {
|
||||
commit_error
|
||||
};
|
||||
|
||||
extern enum commit_action get_commit_action(struct rev_info *revs, struct commit *commit);
|
||||
extern enum commit_action simplify_commit(struct rev_info *revs, struct commit *commit);
|
||||
|
||||
#endif
|
||||
|
||||
73
t/gitweb-lib.sh
Normal file
73
t/gitweb-lib.sh
Normal file
@@ -0,0 +1,73 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2007 Jakub Narebski
|
||||
#
|
||||
|
||||
gitweb_init () {
|
||||
safe_pwd="$(perl -MPOSIX=getcwd -e 'print quotemeta(getcwd)')"
|
||||
cat >gitweb_config.perl <<EOF
|
||||
#!/usr/bin/perl
|
||||
|
||||
# gitweb configuration for tests
|
||||
|
||||
our \$version = 'current';
|
||||
our \$GIT = 'git';
|
||||
our \$projectroot = "$safe_pwd";
|
||||
our \$project_maxdepth = 8;
|
||||
our \$home_link_str = 'projects';
|
||||
our \$site_name = '[localhost]';
|
||||
our \$site_header = '';
|
||||
our \$site_footer = '';
|
||||
our \$home_text = 'indextext.html';
|
||||
our @stylesheets = ('file:///$TEST_DIRECTORY/../gitweb/gitweb.css');
|
||||
our \$logo = 'file:///$TEST_DIRECTORY/../gitweb/git-logo.png';
|
||||
our \$favicon = 'file:///$TEST_DIRECTORY/../gitweb/git-favicon.png';
|
||||
our \$projects_list = '';
|
||||
our \$export_ok = '';
|
||||
our \$strict_export = '';
|
||||
|
||||
EOF
|
||||
|
||||
cat >.git/description <<EOF
|
||||
$0 test repository
|
||||
EOF
|
||||
}
|
||||
|
||||
gitweb_run () {
|
||||
GATEWAY_INTERFACE='CGI/1.1'
|
||||
HTTP_ACCEPT='*/*'
|
||||
REQUEST_METHOD='GET'
|
||||
SCRIPT_NAME="$TEST_DIRECTORY/../gitweb/gitweb.perl"
|
||||
QUERY_STRING=""$1""
|
||||
PATH_INFO=""$2""
|
||||
export GATEWAY_INTERFACE HTTP_ACCEPT REQUEST_METHOD \
|
||||
SCRIPT_NAME QUERY_STRING PATH_INFO
|
||||
|
||||
GITWEB_CONFIG=$(pwd)/gitweb_config.perl
|
||||
export GITWEB_CONFIG
|
||||
|
||||
# some of git commands write to STDERR on error, but this is not
|
||||
# written to web server logs, so we are not interested in that:
|
||||
# we are interested only in properly formatted errors/warnings
|
||||
rm -f gitweb.log &&
|
||||
perl -- "$SCRIPT_NAME" \
|
||||
>gitweb.output 2>gitweb.log &&
|
||||
if grep '^[[]' gitweb.log >/dev/null 2>&1; then false; else true; fi
|
||||
|
||||
# gitweb.log is left for debugging
|
||||
# gitweb.output is used to parse http output
|
||||
}
|
||||
|
||||
. ./test-lib.sh
|
||||
|
||||
if ! test_have_prereq PERL; then
|
||||
say 'skipping gitweb tests, perl not available'
|
||||
test_done
|
||||
fi
|
||||
|
||||
perl -MEncode -e 'decode_utf8("", Encode::FB_CROAK)' >/dev/null 2>&1 || {
|
||||
say 'skipping gitweb tests, perl version is too old'
|
||||
test_done
|
||||
}
|
||||
|
||||
gitweb_init
|
||||
41
t/lib-patch-mode.sh
Executable file
41
t/lib-patch-mode.sh
Executable file
@@ -0,0 +1,41 @@
|
||||
. ./test-lib.sh
|
||||
|
||||
if ! test_have_prereq PERL; then
|
||||
say 'skipping --patch tests, perl not available'
|
||||
test_done
|
||||
fi
|
||||
|
||||
set_state () {
|
||||
echo "$3" > "$1" &&
|
||||
git add "$1" &&
|
||||
echo "$2" > "$1"
|
||||
}
|
||||
|
||||
save_state () {
|
||||
noslash="$(echo "$1" | tr / _)" &&
|
||||
cat "$1" > _worktree_"$noslash" &&
|
||||
git show :"$1" > _index_"$noslash"
|
||||
}
|
||||
|
||||
set_and_save_state () {
|
||||
set_state "$@" &&
|
||||
save_state "$1"
|
||||
}
|
||||
|
||||
verify_state () {
|
||||
test "$(cat "$1")" = "$2" &&
|
||||
test "$(git show :"$1")" = "$3"
|
||||
}
|
||||
|
||||
verify_saved_state () {
|
||||
noslash="$(echo "$1" | tr / _)" &&
|
||||
verify_state "$1" "$(cat _worktree_"$noslash")" "$(cat _index_"$noslash")"
|
||||
}
|
||||
|
||||
save_head () {
|
||||
git rev-parse HEAD > _head
|
||||
}
|
||||
|
||||
verify_saved_head () {
|
||||
test "$(cat _head)" = "$(git rev-parse HEAD)"
|
||||
}
|
||||
75
t/t0006-date.sh
Executable file
75
t/t0006-date.sh
Executable file
@@ -0,0 +1,75 @@
|
||||
#!/bin/sh
|
||||
|
||||
test_description='test date parsing and printing'
|
||||
. ./test-lib.sh
|
||||
|
||||
# arbitrary reference time: 2009-08-30 19:20:00
|
||||
TEST_DATE_NOW=1251660000; export TEST_DATE_NOW
|
||||
|
||||
check_show() {
|
||||
t=$(($TEST_DATE_NOW - $1))
|
||||
echo "$t -> $2" >expect
|
||||
test_expect_${3:-success} "relative date ($2)" "
|
||||
test-date show $t >actual &&
|
||||
test_cmp expect actual
|
||||
"
|
||||
}
|
||||
|
||||
check_show 5 '5 seconds ago'
|
||||
check_show 300 '5 minutes ago'
|
||||
check_show 18000 '5 hours ago'
|
||||
check_show 432000 '5 days ago'
|
||||
check_show 1728000 '3 weeks ago'
|
||||
check_show 13000000 '5 months ago'
|
||||
check_show 37500000 '1 year, 2 months ago'
|
||||
check_show 55188000 '1 year, 9 months ago'
|
||||
check_show 630000000 '20 years ago'
|
||||
|
||||
check_parse() {
|
||||
echo "$1 -> $2" >expect
|
||||
test_expect_${3:-success} "parse date ($1)" "
|
||||
test-date parse '$1' >actual &&
|
||||
test_cmp expect actual
|
||||
"
|
||||
}
|
||||
|
||||
check_parse 2008 bad
|
||||
check_parse 2008-02 bad
|
||||
check_parse 2008-02-14 bad
|
||||
check_parse '2008-02-14 20:30:45' '2008-02-14 20:30:45 +0000'
|
||||
|
||||
check_approxidate() {
|
||||
echo "$1 -> $2 +0000" >expect
|
||||
test_expect_${3:-success} "parse approxidate ($1)" "
|
||||
test-date approxidate '$1' >actual &&
|
||||
test_cmp expect actual
|
||||
"
|
||||
}
|
||||
|
||||
check_approxidate now '2009-08-30 19:20:00'
|
||||
check_approxidate '5 seconds ago' '2009-08-30 19:19:55'
|
||||
check_approxidate 5.seconds.ago '2009-08-30 19:19:55'
|
||||
check_approxidate 10.minutes.ago '2009-08-30 19:10:00'
|
||||
check_approxidate yesterday '2009-08-29 19:20:00'
|
||||
check_approxidate 3.days.ago '2009-08-27 19:20:00'
|
||||
check_approxidate 3.weeks.ago '2009-08-09 19:20:00'
|
||||
check_approxidate 3.months.ago '2009-05-30 19:20:00'
|
||||
check_approxidate 2.years.3.months.ago '2007-05-30 19:20:00'
|
||||
|
||||
check_approxidate '6am yesterday' '2009-08-29 06:00:00'
|
||||
check_approxidate '6pm yesterday' '2009-08-29 18:00:00'
|
||||
check_approxidate '3:00' '2009-08-30 03:00:00'
|
||||
check_approxidate '15:00' '2009-08-30 15:00:00'
|
||||
check_approxidate 'noon today' '2009-08-30 12:00:00'
|
||||
check_approxidate 'noon yesterday' '2009-08-29 12:00:00'
|
||||
|
||||
check_approxidate 'last tuesday' '2009-08-25 19:20:00'
|
||||
check_approxidate 'July 5th' '2009-07-05 19:20:00'
|
||||
check_approxidate '06/05/2009' '2009-06-05 19:20:00'
|
||||
check_approxidate '06.05.2009' '2009-05-06 19:20:00'
|
||||
|
||||
check_approxidate 'Jun 6, 5AM' '2009-06-06 05:00:00'
|
||||
check_approxidate '5AM Jun 6' '2009-06-06 05:00:00'
|
||||
check_approxidate '6AM, June 7, 2009' '2009-06-07 06:00:00'
|
||||
|
||||
test_done
|
||||
25
t/t1009-read-tree-new-index.sh
Executable file
25
t/t1009-read-tree-new-index.sh
Executable file
@@ -0,0 +1,25 @@
|
||||
#!/bin/sh
|
||||
|
||||
test_description='test read-tree into a fresh index file'
|
||||
|
||||
. ./test-lib.sh
|
||||
|
||||
test_expect_success setup '
|
||||
echo one >a &&
|
||||
git add a &&
|
||||
git commit -m initial
|
||||
'
|
||||
|
||||
test_expect_success 'non-existent index file' '
|
||||
rm -f new-index &&
|
||||
GIT_INDEX_FILE=new-index git read-tree master
|
||||
'
|
||||
|
||||
test_expect_success 'empty index file' '
|
||||
rm -f new-index &&
|
||||
> new-index &&
|
||||
GIT_INDEX_FILE=new-index git read-tree master
|
||||
'
|
||||
|
||||
test_done
|
||||
|
||||
@@ -48,4 +48,13 @@ test_expect_success \
|
||||
'git checkout-index conflicting paths.' \
|
||||
'test -f path0 && test -d path1 && test -f path1/file1'
|
||||
|
||||
test_expect_success SYMLINKS 'checkout-index -f twice with --prefix' '
|
||||
mkdir -p tar/get &&
|
||||
ln -s tar/get there &&
|
||||
echo first &&
|
||||
git checkout-index -a -f --prefix=there/ &&
|
||||
echo second &&
|
||||
git checkout-index -a -f --prefix=there/
|
||||
'
|
||||
|
||||
test_done
|
||||
|
||||
40
t/t2015-checkout-unborn.sh
Executable file
40
t/t2015-checkout-unborn.sh
Executable file
@@ -0,0 +1,40 @@
|
||||
#!/bin/sh
|
||||
|
||||
test_description='checkout from unborn branch protects contents'
|
||||
. ./test-lib.sh
|
||||
|
||||
test_expect_success 'setup' '
|
||||
mkdir parent &&
|
||||
(cd parent &&
|
||||
git init &&
|
||||
echo content >file &&
|
||||
git add file &&
|
||||
git commit -m base
|
||||
) &&
|
||||
git fetch parent master:origin
|
||||
'
|
||||
|
||||
test_expect_success 'checkout from unborn preserves untracked files' '
|
||||
echo precious >expect &&
|
||||
echo precious >file &&
|
||||
test_must_fail git checkout -b new origin &&
|
||||
test_cmp expect file
|
||||
'
|
||||
|
||||
test_expect_success 'checkout from unborn preserves index contents' '
|
||||
echo precious >expect &&
|
||||
echo precious >file &&
|
||||
git add file &&
|
||||
test_must_fail git checkout -b new origin &&
|
||||
test_cmp expect file &&
|
||||
git show :file >file &&
|
||||
test_cmp expect file
|
||||
'
|
||||
|
||||
test_expect_success 'checkout from unborn merges identical index contents' '
|
||||
echo content >file &&
|
||||
git add file &&
|
||||
git checkout -b new origin
|
||||
'
|
||||
|
||||
test_done
|
||||
107
t/t2016-checkout-patch.sh
Executable file
107
t/t2016-checkout-patch.sh
Executable file
@@ -0,0 +1,107 @@
|
||||
#!/bin/sh
|
||||
|
||||
test_description='git checkout --patch'
|
||||
|
||||
. ./lib-patch-mode.sh
|
||||
|
||||
test_expect_success 'setup' '
|
||||
mkdir dir &&
|
||||
echo parent > dir/foo &&
|
||||
echo dummy > bar &&
|
||||
git add bar dir/foo &&
|
||||
git commit -m initial &&
|
||||
test_tick &&
|
||||
test_commit second dir/foo head &&
|
||||
set_and_save_state bar bar_work bar_index &&
|
||||
save_head
|
||||
'
|
||||
|
||||
# note: bar sorts before dir/foo, so the first 'n' is always to skip 'bar'
|
||||
|
||||
test_expect_success 'saying "n" does nothing' '
|
||||
set_and_save_state dir/foo work head &&
|
||||
(echo n; echo n) | git checkout -p &&
|
||||
verify_saved_state bar &&
|
||||
verify_saved_state dir/foo
|
||||
'
|
||||
|
||||
test_expect_success 'git checkout -p' '
|
||||
(echo n; echo y) | git checkout -p &&
|
||||
verify_saved_state bar &&
|
||||
verify_state dir/foo head head
|
||||
'
|
||||
|
||||
test_expect_success 'git checkout -p with staged changes' '
|
||||
set_state dir/foo work index
|
||||
(echo n; echo y) | git checkout -p &&
|
||||
verify_saved_state bar &&
|
||||
verify_state dir/foo index index
|
||||
'
|
||||
|
||||
test_expect_success 'git checkout -p HEAD with NO staged changes: abort' '
|
||||
set_and_save_state dir/foo work head &&
|
||||
(echo n; echo y; echo n) | git checkout -p HEAD &&
|
||||
verify_saved_state bar &&
|
||||
verify_saved_state dir/foo
|
||||
'
|
||||
|
||||
test_expect_success 'git checkout -p HEAD with NO staged changes: apply' '
|
||||
(echo n; echo y; echo y) | git checkout -p HEAD &&
|
||||
verify_saved_state bar &&
|
||||
verify_state dir/foo head head
|
||||
'
|
||||
|
||||
test_expect_success 'git checkout -p HEAD with change already staged' '
|
||||
set_state dir/foo index index
|
||||
# the third n is to get out in case it mistakenly does not apply
|
||||
(echo n; echo y; echo n) | git checkout -p HEAD &&
|
||||
verify_saved_state bar &&
|
||||
verify_state dir/foo head head
|
||||
'
|
||||
|
||||
test_expect_success 'git checkout -p HEAD^' '
|
||||
# the third n is to get out in case it mistakenly does not apply
|
||||
(echo n; echo y; echo n) | git checkout -p HEAD^ &&
|
||||
verify_saved_state bar &&
|
||||
verify_state dir/foo parent parent
|
||||
'
|
||||
|
||||
# The idea in the rest is that bar sorts first, so we always say 'y'
|
||||
# first and if the path limiter fails it'll apply to bar instead of
|
||||
# dir/foo. There's always an extra 'n' to reject edits to dir/foo in
|
||||
# the failure case (and thus get out of the loop).
|
||||
|
||||
test_expect_success 'path limiting works: dir' '
|
||||
set_state dir/foo work head &&
|
||||
(echo y; echo n) | git checkout -p dir &&
|
||||
verify_saved_state bar &&
|
||||
verify_state dir/foo head head
|
||||
'
|
||||
|
||||
test_expect_success 'path limiting works: -- dir' '
|
||||
set_state dir/foo work head &&
|
||||
(echo y; echo n) | git checkout -p -- dir &&
|
||||
verify_saved_state bar &&
|
||||
verify_state dir/foo head head
|
||||
'
|
||||
|
||||
test_expect_success 'path limiting works: HEAD^ -- dir' '
|
||||
# the third n is to get out in case it mistakenly does not apply
|
||||
(echo y; echo n; echo n) | git checkout -p HEAD^ -- dir &&
|
||||
verify_saved_state bar &&
|
||||
verify_state dir/foo parent parent
|
||||
'
|
||||
|
||||
test_expect_success 'path limiting works: foo inside dir' '
|
||||
set_state dir/foo work head &&
|
||||
# the third n is to get out in case it mistakenly does not apply
|
||||
(echo y; echo n; echo n) | (cd dir && git checkout -p foo) &&
|
||||
verify_saved_state bar &&
|
||||
verify_state dir/foo head head
|
||||
'
|
||||
|
||||
test_expect_success 'none of this moved HEAD' '
|
||||
verify_saved_head
|
||||
'
|
||||
|
||||
test_done
|
||||
@@ -201,4 +201,23 @@ test_expect_success 'drop -q is quiet' '
|
||||
test ! -s output.out
|
||||
'
|
||||
|
||||
test_expect_success 'stash -k' '
|
||||
echo bar3 > file &&
|
||||
echo bar4 > file2 &&
|
||||
git add file2 &&
|
||||
git stash -k &&
|
||||
test bar,bar4 = $(cat file),$(cat file2)
|
||||
'
|
||||
|
||||
test_expect_success 'stash --invalid-option' '
|
||||
echo bar5 > file &&
|
||||
echo bar6 > file2 &&
|
||||
git add file2 &&
|
||||
test_must_fail git stash --invalid-option &&
|
||||
test_must_fail git stash save --invalid-option &&
|
||||
test bar5,bar6 = $(cat file),$(cat file2) &&
|
||||
git stash -- -message-starting-with-dash &&
|
||||
test bar,bar2 = $(cat file),$(cat file2)
|
||||
'
|
||||
|
||||
test_done
|
||||
|
||||
55
t/t3904-stash-patch.sh
Executable file
55
t/t3904-stash-patch.sh
Executable file
@@ -0,0 +1,55 @@
|
||||
#!/bin/sh
|
||||
|
||||
test_description='git checkout --patch'
|
||||
. ./lib-patch-mode.sh
|
||||
|
||||
test_expect_success 'setup' '
|
||||
mkdir dir &&
|
||||
echo parent > dir/foo &&
|
||||
echo dummy > bar &&
|
||||
git add bar dir/foo &&
|
||||
git commit -m initial &&
|
||||
test_tick &&
|
||||
test_commit second dir/foo head &&
|
||||
echo index > dir/foo &&
|
||||
git add dir/foo &&
|
||||
set_and_save_state bar bar_work bar_index &&
|
||||
save_head
|
||||
'
|
||||
|
||||
# note: bar sorts before dir, so the first 'n' is always to skip 'bar'
|
||||
|
||||
test_expect_success 'saying "n" does nothing' '
|
||||
set_state dir/foo work index
|
||||
(echo n; echo n) | test_must_fail git stash save -p &&
|
||||
verify_state dir/foo work index &&
|
||||
verify_saved_state bar
|
||||
'
|
||||
|
||||
test_expect_success 'git stash -p' '
|
||||
(echo n; echo y) | git stash save -p &&
|
||||
verify_state dir/foo head index &&
|
||||
verify_saved_state bar &&
|
||||
git reset --hard &&
|
||||
git stash apply &&
|
||||
verify_state dir/foo work head &&
|
||||
verify_state bar dummy dummy
|
||||
'
|
||||
|
||||
test_expect_success 'git stash -p --no-keep-index' '
|
||||
set_state dir/foo work index &&
|
||||
set_state bar bar_work bar_index &&
|
||||
(echo n; echo y) | git stash save -p --no-keep-index &&
|
||||
verify_state dir/foo head head &&
|
||||
verify_state bar bar_work dummy &&
|
||||
git reset --hard &&
|
||||
git stash apply --index &&
|
||||
verify_state dir/foo work index &&
|
||||
verify_state bar dummy bar_index
|
||||
'
|
||||
|
||||
test_expect_success 'none of this moved HEAD' '
|
||||
verify_saved_head
|
||||
'
|
||||
|
||||
test_done
|
||||
@@ -207,6 +207,7 @@ log --root --cc --patch-with-stat --summary master
|
||||
log -SF master
|
||||
log -SF -p master
|
||||
log --decorate --all
|
||||
log --decorate=full --all
|
||||
|
||||
rev-list --parents HEAD
|
||||
rev-list --children HEAD
|
||||
|
||||
34
t/t4013/diff.log_--decorate=full_--all
Normal file
34
t/t4013/diff.log_--decorate=full_--all
Normal file
@@ -0,0 +1,34 @@
|
||||
$ git log --decorate=full --all
|
||||
commit 59d314ad6f356dd08601a4cd5e530381da3e3c64 (refs/heads/master)
|
||||
Merge: 9a6d494 c7a2ab9
|
||||
Author: A U Thor <author@example.com>
|
||||
Date: Mon Jun 26 00:04:00 2006 +0000
|
||||
|
||||
Merge branch 'side'
|
||||
|
||||
commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a (refs/heads/side)
|
||||
Author: A U Thor <author@example.com>
|
||||
Date: Mon Jun 26 00:03:00 2006 +0000
|
||||
|
||||
Side
|
||||
|
||||
commit 9a6d4949b6b76956d9d5e26f2791ec2ceff5fdc0
|
||||
Author: A U Thor <author@example.com>
|
||||
Date: Mon Jun 26 00:02:00 2006 +0000
|
||||
|
||||
Third
|
||||
|
||||
commit 1bde4ae5f36c8d9abe3a0fce0c6aab3c4a12fe44
|
||||
Author: A U Thor <author@example.com>
|
||||
Date: Mon Jun 26 00:01:00 2006 +0000
|
||||
|
||||
Second
|
||||
|
||||
This is the second commit.
|
||||
|
||||
commit 444ac553ac7612cc88969031b02b3767fb8a353a (refs/heads/initial)
|
||||
Author: A U Thor <author@example.com>
|
||||
Date: Mon Jun 26 00:00:00 2006 +0000
|
||||
|
||||
Initial
|
||||
$
|
||||
31
t/t4039-diff-assume-unchanged.sh
Executable file
31
t/t4039-diff-assume-unchanged.sh
Executable file
@@ -0,0 +1,31 @@
|
||||
#!/bin/sh
|
||||
|
||||
test_description='diff with assume-unchanged entries'
|
||||
|
||||
. ./test-lib.sh
|
||||
|
||||
# external diff has been tested in t4020-diff-external.sh
|
||||
|
||||
test_expect_success 'setup' '
|
||||
echo zero > zero &&
|
||||
git add zero &&
|
||||
git commit -m zero &&
|
||||
echo one > one &&
|
||||
echo two > two &&
|
||||
git add one two &&
|
||||
git commit -m onetwo &&
|
||||
git update-index --assume-unchanged one &&
|
||||
echo borked >> one &&
|
||||
test "$(git ls-files -v one)" = "h one"
|
||||
'
|
||||
|
||||
test_expect_success 'diff-index does not examine assume-unchanged entries' '
|
||||
git diff-index HEAD^ -- one | grep -q 5626abf0f72e58d7a153368ba57db4c673c0e171
|
||||
'
|
||||
|
||||
test_expect_success 'diff-files does not examine assume-unchanged entries' '
|
||||
rm one &&
|
||||
test -z "$(git diff-files -- one)"
|
||||
'
|
||||
|
||||
test_done
|
||||
@@ -11,18 +11,26 @@ test_expect_success 'split sample box' \
|
||||
'git mailsplit -o. "$TEST_DIRECTORY"/t5100/sample.mbox >last &&
|
||||
last=`cat last` &&
|
||||
echo total is $last &&
|
||||
test `cat last` = 13'
|
||||
test `cat last` = 14'
|
||||
|
||||
check_mailinfo () {
|
||||
mail=$1 opt=$2
|
||||
mo="$mail$opt"
|
||||
git mailinfo -u $opt msg$mo patch$mo <$mail >info$mo &&
|
||||
test_cmp "$TEST_DIRECTORY"/t5100/msg$mo msg$mo &&
|
||||
test_cmp "$TEST_DIRECTORY"/t5100/patch$mo patch$mo &&
|
||||
test_cmp "$TEST_DIRECTORY"/t5100/info$mo info$mo
|
||||
}
|
||||
|
||||
|
||||
for mail in `echo 00*`
|
||||
do
|
||||
test_expect_success "mailinfo $mail" '
|
||||
git mailinfo -u msg$mail patch$mail <$mail >info$mail &&
|
||||
echo msg &&
|
||||
test_cmp "$TEST_DIRECTORY"/t5100/msg$mail msg$mail &&
|
||||
echo patch &&
|
||||
test_cmp "$TEST_DIRECTORY"/t5100/patch$mail patch$mail &&
|
||||
echo info &&
|
||||
test_cmp "$TEST_DIRECTORY"/t5100/info$mail info$mail
|
||||
check_mailinfo $mail "" &&
|
||||
if test -f "$TEST_DIRECTORY"/t5100/msg$mail--scissors
|
||||
then
|
||||
check_mailinfo $mail --scissors
|
||||
fi
|
||||
'
|
||||
done
|
||||
|
||||
|
||||
5
t/t5100/info0014
Normal file
5
t/t5100/info0014
Normal file
@@ -0,0 +1,5 @@
|
||||
Author: Junio Hamano
|
||||
Email: junkio@cox.net
|
||||
Subject: BLAH ONE
|
||||
Date: Thu, 20 Aug 2009 17:18:22 -0700
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user