aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJunio C Hamano <junkio@cox.net>2006-08-26 01:08:39 -0700
committerJunio C Hamano <junkio@cox.net>2006-08-26 01:08:39 -0700
commitb4c27c186f6282ead5d2af0cfd9b6015b011bc38 (patch)
tree4ad1f74af2cd95e8cf0ee82a4b06d6c1ffae5611
parent903acca75329841996bbf0c3a32a7cfeb3ae0d0f (diff)
parenta7f051987c5f020e60da1e5d6ddefc3d443d3299 (diff)
downloadgit-b4c27c186f6282ead5d2af0cfd9b6015b011bc38.tar.gz
git-b4c27c186f6282ead5d2af0cfd9b6015b011bc38.tar.xz
Merge branch 'master' into gl/web
* master: (34 commits) gitweb: git_annotate didn't expect negative numeric timezone git-svn: add the 'dcommit' command git-svn: recommend rebase for syncing against an SVN repo git-svn: establish new connections on commit after fork describe: fix off-by-one error in --abbrev=40 handling git-svn(1): improve asciidoc markup gitview.txt: improve asciidoc markup git(7): put the synopsis in a verse style paragraph gitk(1): expand the manpage to look less like a template git-blame(1): mention options in the synopsis and advertise pickaxe git-ls-remote(1): document --upload-pack git-apply(1): document missing options and improve existing ones update-index -g n is in fact unused, and is later shadowed. use name[len] in switch directly, instead of creating a shadowed variable. builtin-grep.c: remove unused debugging piece. remove ugly shadowing of loop indexes in subloops. missing 'static' keywords git_dir holds pointers to local strings, hence MUST be const. avoid to use error that shadows the function name, use err instead. ...
-rw-r--r--Documentation/git-apply.txt46
-rw-r--r--Documentation/git-blame.txt29
-rw-r--r--Documentation/git-ls-remote.txt18
-rw-r--r--Documentation/git-svn.txt248
-rw-r--r--Documentation/git-update-index.txt4
-rw-r--r--Documentation/git.txt3
-rw-r--r--Documentation/gitk.txt60
-rw-r--r--Makefile1
-rw-r--r--blame.c6
-rw-r--r--builtin-apply.c10
-rw-r--r--builtin-cat-file.c29
-rw-r--r--builtin-commit-tree.c2
-rw-r--r--builtin-diff-stages.c2
-rw-r--r--builtin-diff.c6
-rw-r--r--builtin-grep.c3
-rw-r--r--builtin-mv.c117
-rw-r--r--builtin-pack-objects.c14
-rw-r--r--builtin-push.c10
-rw-r--r--builtin-read-tree.c2
-rw-r--r--builtin-show-branch.c4
-rw-r--r--builtin-tar-tree.c31
-rw-r--r--builtin-unpack-objects.c8
-rw-r--r--builtin-update-index.c12
-rw-r--r--builtin-update-ref.c2
-rw-r--r--builtin-write-tree.c4
-rw-r--r--cache-tree.c6
-rw-r--r--cache.h15
-rw-r--r--combine-diff.c14
-rw-r--r--commit.c14
-rw-r--r--connect.c6
-rw-r--r--contrib/gitview/gitview.txt56
-rw-r--r--convert-objects.c8
-rw-r--r--csum-file.c2
-rw-r--r--date.c6
-rw-r--r--describe.c4
-rw-r--r--diff-delta.c2
-rw-r--r--diff-lib.c7
-rw-r--r--diff.c16
-rw-r--r--diffcore-break.c2
-rw-r--r--diffcore-rename.c2
-rw-r--r--dump-cache-tree.c2
-rw-r--r--environment.c7
-rw-r--r--fetch-pack.c2
-rw-r--r--fetch.c2
-rw-r--r--fsck-objects.c2
-rwxr-xr-xgit-send-email.perl2
-rwxr-xr-xgit-svn.perl39
-rw-r--r--git.c6
-rwxr-xr-xgitweb/gitweb.perl2
-rw-r--r--http-fetch.c8
-rw-r--r--http-push.c14
-rw-r--r--index-pack.c16
-rw-r--r--merge-tree.c2
-rw-r--r--mktree.c4
-rw-r--r--object.c4
-rw-r--r--pack-check.c6
-rw-r--r--pack-redundant.c14
-rw-r--r--patch-id.c2
-rw-r--r--read-cache.c4
-rw-r--r--receive-pack.c4
-rw-r--r--refs.c10
-rw-r--r--revision.c2
-rw-r--r--send-pack.c6
-rw-r--r--sha1_file.c47
-rw-r--r--sha1_name.c30
-rw-r--r--ssh-fetch.c2
-rwxr-xr-xt/t7001-mv.sh4
-rw-r--r--tree-diff.c3
-rw-r--r--tree-walk.c4
-rw-r--r--tree.c2
-rw-r--r--unpack-trees.c4
-rw-r--r--upload-pack.c2
-rw-r--r--write_or_die.c20
73 files changed, 661 insertions, 448 deletions
diff --git a/Documentation/git-apply.txt b/Documentation/git-apply.txt
index 2ff74949a..20e12ceda 100644
--- a/Documentation/git-apply.txt
+++ b/Documentation/git-apply.txt
@@ -10,9 +10,10 @@ SYNOPSIS
--------
[verse]
'git-apply' [--stat] [--numstat] [--summary] [--check] [--index] [--apply]
- [--no-add] [--index-info] [--allow-binary-replacement] [-z] [-pNUM]
- [-CNUM] [--whitespace=<nowarn|warn|error|error-all|strip>]
- [<patch>...]
+ [--no-add] [--index-info] [--allow-binary-replacement | --binary]
+ [-R | --reverse] [--reject] [-z] [-pNUM] [-CNUM] [--inaccurate-eof]
+ [--whitespace=<nowarn|warn|error|error-all|strip>] [--exclude=PATH]
+ [--cached] [--verbose] [<patch>...]
DESCRIPTION
-----------
@@ -55,6 +56,11 @@ OPTIONS
up-to-date, it is flagged as an error. This flag also
causes the index file to be updated.
+--cached::
+ Apply a patch without touching the working tree. Instead, take the
+ cached data, apply the patch, and store the result in the index,
+ without using the working tree. This implies '--index'.
+
--index-info::
Newer git-diff output has embedded 'index information'
for each blob to help identify the original version that
@@ -62,6 +68,16 @@ OPTIONS
the original version of the blob is available locally,
outputs information about them to the standard output.
+-R, --reverse::
+ Apply the patch in reverse.
+
+--reject::
+ For atomicity, gitlink:git-apply[1] by default fails the whole patch and
+ does not touch the working tree when some of the hunks
+ do not apply. This option makes it apply
+ the parts of the patch that are applicable, and send the
+ rejected hunks to the standard output of the command.
+
-z::
When showing the index information, do not munge paths,
but use NUL terminated machine readable format. Without
@@ -80,8 +96,8 @@ OPTIONS
ever ignored.
--apply::
- If you use any of the options marked ``Turns off
- "apply"'' above, git-apply reads and outputs the
+ If you use any of the options marked "Turns off
+ 'apply'" above, gitlink:git-apply[1] reads and outputs the
information you asked without actually applying the
patch. Give this flag after those flags to also apply
the patch.
@@ -93,7 +109,7 @@ OPTIONS
the result with this option, which would apply the
deletion part but not addition part.
---allow-binary-replacement::
+--allow-binary-replacement, --binary::
When applying a patch, which is a git-enhanced patch
that was prepared to record the pre- and post-image object
name in full, and the path being patched exactly matches
@@ -104,13 +120,18 @@ OPTIONS
result. This allows binary files to be patched in a
very limited way.
+--exclude=<path-pattern>::
+ Don't apply changes to files matching the given path pattern. This can
+ be useful when importing patchsets, where you want to exclude certain
+ files or directories.
+
--whitespace=<option>::
When applying a patch, detect a new or modified line
that ends with trailing whitespaces (this includes a
line that solely consists of whitespaces). By default,
the command outputs warning messages and applies the
patch.
- When `git-apply` is used for statistics and not applying a
+ When gitlink:git-apply[1] is used for statistics and not applying a
patch, it defaults to `nowarn`.
You can use different `<option>` to control this
behavior:
@@ -124,6 +145,17 @@ OPTIONS
* `strip` outputs warnings for a few such errors, strips out the
trailing whitespaces and applies the patch.
+--inacurate-eof::
+ Under certain circumstances, some versions of diff do not correctly
+ detect a missing new-line at the end of the file. As a result, patches
+ created by such diff programs do not record incomplete lines
+ correctly. This option adds support for applying such patches by
+ working around this bug.
+
+--verbose::
+ Report progress to stderr. By default, only a message about the
+ current patch being applied will be printed. This option will cause
+ additional information to be reported.
Configuration
-------------
diff --git a/Documentation/git-blame.txt b/Documentation/git-blame.txt
index bfed94591..e1f89444a 100644
--- a/Documentation/git-blame.txt
+++ b/Documentation/git-blame.txt
@@ -3,21 +3,38 @@ git-blame(1)
NAME
----
-git-blame - Blame file lines on commits
+git-blame - Show what revision and author last modified each line of a file
SYNOPSIS
--------
-git-blame file [options] file [revision]
+'git-blame' [-c] [-l] [-t] [-S <revs-file>] [--] <file> [<rev>]
DESCRIPTION
-----------
-Annotates each line in the given file with information from the commit
-which introduced the line. Start annotation from the given revision.
+
+Annotates each line in the given file with information from the revision which
+last modified the line. Optionally, start annotating from the given revision.
+
+This report doesn't tell you anything about lines which have been deleted or
+replaced; you need to use a tool such as gitlink:git-diff[1] or the "pickaxe"
+interface briefly mentioned in the following paragraph.
+
+Apart from supporting file annotation, git also supports searching the
+development history for when a code snippet occured in a change. This makes it
+possible to track when a code snippet was added to a file, moved or copied
+between files, and eventually deleted or replaced. It works by searching for
+a text string in the diff. A small example:
+
+-----------------------------------------------------------------------------
+$ git log --pretty=oneline -S'blame_usage'
+5040f17eba15504bad66b14a645bddd9b015ebb7 blame -S <ancestry-file>
+ea4c7f9bf69e781dd0cd88d2bccb2bf5cc15c9a7 git-blame: Make the output
+-----------------------------------------------------------------------------
OPTIONS
-------
-c, --compatibility::
- Use the same output mode as git-annotate (Default: off).
+ Use the same output mode as gitlink:git-annotate[1] (Default: off).
-l, --long::
Show long rev (Default: off).
@@ -26,7 +43,7 @@ OPTIONS
Show raw timestamp (Default: off).
-S, --rev-file <revs-file>::
- Use revs from revs-file instead of calling git-rev-list.
+ Use revs from revs-file instead of calling gitlink:git-rev-list[1].
-h, --help::
Show help message.
diff --git a/Documentation/git-ls-remote.txt b/Documentation/git-ls-remote.txt
index ae4c1a250..c8a4c5a4d 100644
--- a/Documentation/git-ls-remote.txt
+++ b/Documentation/git-ls-remote.txt
@@ -3,16 +3,19 @@ git-ls-remote(1)
NAME
----
-git-ls-remote - Look at references other repository has
+git-ls-remote - List references in a remote repository
SYNOPSIS
--------
-'git-ls-remote' [--heads] [--tags] <repository> <refs>...
+[verse]
+'git-ls-remote' [--heads] [--tags] [-u <exec> | --upload-pack <exec>]
+ <repository> <refs>...
DESCRIPTION
-----------
-Displays the references other repository has.
+Displays references available in a remote repository along with the associated
+commit IDs.
OPTIONS
@@ -23,9 +26,16 @@ OPTIONS
both, references stored in refs/heads and refs/tags are
displayed.
+-u <exec>, --upload-pack=<exec>::
+ Specify the full path of gitlink:git-upload-pack[1] on the remote
+ host. This allows listing references from repositories accessed via
+ SSH and where the SSH deamon does not use the PATH configured by the
+ user. Also see the '--exec' option for gitlink:git-peek-remote[1].
+
<repository>::
Location of the repository. The shorthand defined in
- $GIT_DIR/branches/ can be used.
+ $GIT_DIR/branches/ can be used. Use "." (dot) to list references in
+ the local repository.
<refs>...::
When unspecified, all references, after filtering done
diff --git a/Documentation/git-svn.txt b/Documentation/git-svn.txt
index 7d8680984..b7b63f713 100644
--- a/Documentation/git-svn.txt
+++ b/Documentation/git-svn.txt
@@ -12,10 +12,8 @@ SYNOPSIS
DESCRIPTION
-----------
git-svn is a simple conduit for changesets between a single Subversion
-branch and git.
-
-git-svn is not to be confused with git-svnimport. The were designed
-with very different goals in mind.
+branch and git. It is not to be confused with gitlink:git-svnimport[1].
+They were designed with very different goals in mind.
git-svn is designed for an individual developer who wants a
bidirectional flow of changesets between a single branch in Subversion
@@ -34,26 +32,38 @@ git-svnimport is designed for.
COMMANDS
--------
-init::
+--
+
+'init'::
Creates an empty git repository with additional metadata
directories for git-svn. The Subversion URL must be specified
as a command-line argument.
-fetch::
- Fetch unfetched revisions from the Subversion URL we are
- tracking. refs/remotes/git-svn will be updated to the
- latest revision.
+'fetch'::
+
+Fetch unfetched revisions from the Subversion URL we are
+tracking. refs/remotes/git-svn will be updated to the
+latest revision.
+
+Note: You should never attempt to modify the remotes/git-svn
+branch outside of git-svn. Instead, create a branch from
+remotes/git-svn and work on that branch. Use the 'commit'
+command (see below) to write git commits back to
+remotes/git-svn.
- Note: You should never attempt to modify the remotes/git-svn
- branch outside of git-svn. Instead, create a branch from
- remotes/git-svn and work on that branch. Use the 'commit'
- command (see below) to write git commits back to
- remotes/git-svn.
+See '<<fetch-args,Additional Fetch Arguments>>' if you are interested in
+manually joining branches on commit.
- See 'Additional Fetch Arguments' if you are interested in
- manually joining branches on commit.
+'dcommit'::
+ Commit all diffs from the current HEAD directly to the SVN
+ repository, and then rebase or reset (depending on whether or
+ not there is a diff between SVN and HEAD). It is recommended
+ that you run git-svn fetch and rebase (not pull) your commits
+ against the latest changes in the SVN repository.
+ This is advantageous over 'commit' (below) because it produces
+ cleaner, more linear history.
-commit::
+'commit'::
Commit specified commit or tree objects to SVN. This relies on
your imported fetch data being up-to-date. This makes
absolutely no attempts to do patching when committing to SVN, it
@@ -61,9 +71,9 @@ commit::
commit. All merging is assumed to have taken place
independently of git-svn functions.
-rebuild::
+'rebuild'::
Not a part of daily usage, but this is a useful command if
- you've just cloned a repository (using git-clone) that was
+ you've just cloned a repository (using gitlink:git-clone[1]) that was
tracked with git-svn. Unfortunately, git-clone does not clone
git-svn metadata and the svn working tree that git-svn uses for
its operations. This rebuilds the metadata so git-svn can
@@ -71,130 +81,170 @@ rebuild::
specified at the command-line if the directory/repository you're
tracking has moved or changed protocols.
-show-ignore::
+'show-ignore'::
Recursively finds and lists the svn:ignore property on
directories. The output is suitable for appending to
the $GIT_DIR/info/exclude file.
+--
+
OPTIONS
-------
+--
+
-r <ARG>::
--revision <ARG>::
- Only used with the 'fetch' command.
- Takes any valid -r<argument> svn would accept and passes it
- directly to svn. -r<ARG1>:<ARG2> ranges and "{" DATE "}" syntax
- is also supported. This is passed directly to svn, see svn
- documentation for more details.
+Only used with the 'fetch' command.
+
+Takes any valid -r<argument> svn would accept and passes it
+directly to svn. -r<ARG1>:<ARG2> ranges and "{" DATE "}" syntax
+is also supported. This is passed directly to svn, see svn
+documentation for more details.
- This can allow you to make partial mirrors when running fetch.
+This can allow you to make partial mirrors when running fetch.
-::
--stdin::
- Only used with the 'commit' command.
- Read a list of commits from stdin and commit them in reverse
- order. Only the leading sha1 is read from each line, so
- git-rev-list --pretty=oneline output can be used.
+Only used with the 'commit' command.
+
+Read a list of commits from stdin and commit them in reverse
+order. Only the leading sha1 is read from each line, so
+git-rev-list --pretty=oneline output can be used.
--rmdir::
- Only used with the 'commit' command.
- Remove directories from the SVN tree if there are no files left
- behind. SVN can version empty directories, and they are not
- removed by default if there are no files left in them. git
- cannot version empty directories. Enabling this flag will make
- the commit to SVN act like git.
+Only used with the 'commit' command.
+
+Remove directories from the SVN tree if there are no files left
+behind. SVN can version empty directories, and they are not
+removed by default if there are no files left in them. git
+cannot version empty directories. Enabling this flag will make
+the commit to SVN act like git.
- repo-config key: svn.rmdir
+repo-config key: svn.rmdir
-e::
--edit::
- Only used with the 'commit' command.
- Edit the commit message before committing to SVN. This is off by
- default for objects that are commits, and forced on when committing
- tree objects.
+Only used with the 'commit' command.
- repo-config key: svn.edit
+Edit the commit message before committing to SVN. This is off by
+default for objects that are commits, and forced on when committing
+tree objects.
+
+repo-config key: svn.edit
-l<num>::
--find-copies-harder::
- Both of these are only used with the 'commit' command.
- They are both passed directly to git-diff-tree see
- git-diff-tree(1) for more information.
+Both of these are only used with the 'commit' command.
+
+They are both passed directly to git-diff-tree see
+gitlink:git-diff-tree[1] for more information.
- repo-config key: svn.l
- repo-config key: svn.findcopiesharder
+[verse]
+repo-config key: svn.l
+repo-config key: svn.findcopiesharder
-A<filename>::
--authors-file=<filename>::
- Syntax is compatible with the files used by git-svnimport and
- git-cvsimport:
+Syntax is compatible with the files used by git-svnimport and
+git-cvsimport:
------------------------------------------------------------------------
-loginname = Joe User <user@example.com>
+ loginname = Joe User <user@example.com>
------------------------------------------------------------------------
- If this option is specified and git-svn encounters an SVN
- committer name that does not exist in the authors-file, git-svn
- will abort operation. The user will then have to add the
- appropriate entry. Re-running the previous git-svn command
- after the authors-file is modified should continue operation.
+If this option is specified and git-svn encounters an SVN
+committer name that does not exist in the authors-file, git-svn
+will abort operation. The user will then have to add the
+appropriate entry. Re-running the previous git-svn command
+after the authors-file is modified should continue operation.
+
+repo-config key: svn.authors-file
+
+-m::
+--merge::
+-s<strategy>::
+--strategy=<strategy>::
+
+These are only used with the 'dcommit' command.
- repo-config key: svn.authors-file
+Passed directly to git-rebase when using 'dcommit' if a
+'git-reset' cannot be used (see dcommit).
+
+-n::
+--dry-run::
+
+This is only used with the 'dcommit' command.
+
+Print out the series of git arguments that would show
+which diffs would be committed to SVN.
+
+--
ADVANCED OPTIONS
----------------
+--
+
-b<refname>::
--branch <refname>::
- Used with 'fetch' or 'commit'.
+Used with 'fetch' or 'commit'.
- This can be used to join arbitrary git branches to remotes/git-svn
- on new commits where the tree object is equivalent.
+This can be used to join arbitrary git branches to remotes/git-svn
+on new commits where the tree object is equivalent.
- When used with different GIT_SVN_ID values, tags and branches in
- SVN can be tracked this way, as can some merges where the heads
- end up having completely equivalent content. This can even be
- used to track branches across multiple SVN _repositories_.
+When used with different GIT_SVN_ID values, tags and branches in
+SVN can be tracked this way, as can some merges where the heads
+end up having completely equivalent content. This can even be
+used to track branches across multiple SVN _repositories_.
- This option may be specified multiple times, once for each
- branch.
+This option may be specified multiple times, once for each
+branch.
- repo-config key: svn.branch
+repo-config key: svn.branch
-i<GIT_SVN_ID>::
--id <GIT_SVN_ID>::
- This sets GIT_SVN_ID (instead of using the environment). See
- the section on "Tracking Multiple Repositories or Branches" for
- more information on using GIT_SVN_ID.
+
+This sets GIT_SVN_ID (instead of using the environment). See the
+section on
+'<<tracking-multiple-repos,Tracking Multiple Repositories or Branches>>'
+for more information on using GIT_SVN_ID.
+
+--
COMPATIBILITY OPTIONS
---------------------
+--
+
--upgrade::
- Only used with the 'rebuild' command.
+Only used with the 'rebuild' command.
- Run this if you used an old version of git-svn that used
- "git-svn-HEAD" instead of "remotes/git-svn" as the branch
- for tracking the remote.
+Run this if you used an old version of git-svn that used
+"git-svn-HEAD" instead of "remotes/git-svn" as the branch
+for tracking the remote.
--no-ignore-externals::
- Only used with the 'fetch' and 'rebuild' command.
+Only used with the 'fetch' and 'rebuild' command.
+
+By default, git-svn passes --ignore-externals to svn to avoid
+fetching svn:external trees into git. Pass this flag to enable
+externals tracking directly via git.
- By default, git-svn passes --ignore-externals to svn to avoid
- fetching svn:external trees into git. Pass this flag to enable
- externals tracking directly via git.
+Versions of svn that do not support --ignore-externals are
+automatically detected and this flag will be automatically
+enabled for them.
- Versions of svn that do not support --ignore-externals are
- automatically detected and this flag will be automatically
- enabled for them.
+Otherwise, do not enable this flag unless you know what you're
+doing.
- Otherwise, do not enable this flag unless you know what you're
- doing.
+repo-config key: svn.noignoreexternals
- repo-config key: svn.noignoreexternals
+--
Basic Examples
~~~~~~~~~~~~~~
@@ -212,12 +262,26 @@ Tracking and contributing to an Subversion managed-project:
git-svn commit <tree-ish> [<tree-ish_2> ...]
# Commit all the git commits from my-branch that don't exist in SVN:
git-svn commit remotes/git-svn..my-branch
-# Something is committed to SVN, pull the latest into your branch:
- git-svn fetch && git pull . remotes/git-svn
+# Something is committed to SVN, rebase the latest into your branch:
+ git-svn fetch && git rebase remotes/git-svn
# Append svn:ignore settings to the default git exclude file:
git-svn show-ignore >> .git/info/exclude
------------------------------------------------------------------------
+REBASE VS. PULL
+---------------
+
+Originally, git-svn recommended that the remotes/git-svn branch be
+pulled from. This is because the author favored 'git-svn commit B'
+to commit a single head rather than the 'git-svn commit A..B' notation
+to commit multiple commits.
+
+If you use 'git-svn commit A..B' to commit several diffs and you do not
+have the latest remotes/git-svn merged into my-branch, you should use
+'git rebase' to update your work branch instead of 'git pull'. 'pull'
+can cause non-linear history to be flattened when committing into SVN,
+which can lead to merge commits reversing previous commits in SVN.
+
DESIGN PHILOSOPHY
-----------------
Merge tracking in Subversion is lacking and doing branched development
@@ -226,6 +290,7 @@ any automated merge/branch tracking on the Subversion side and leaves it
entirely up to the user on the git side. It's simply not worth it to do
a useful translation when the original signal is weak.
+[[tracking-multiple-repos]]
TRACKING MULTIPLE REPOSITORIES OR BRANCHES
------------------------------------------
This is for advanced users, most users should ignore this section.
@@ -241,6 +306,7 @@ invocation. The interface branch will be remotes/$GIT_SVN_ID, instead of
remotes/git-svn. Any remotes/$GIT_SVN_ID branch should never be modified
by the user outside of git-svn commands.
+[[fetch-args]]
ADDITIONAL FETCH ARGUMENTS
--------------------------
This is for advanced users, most users should ignore this section.
@@ -251,11 +317,15 @@ optionally be specified in the form of sha1 hex sums at the
command-line. Unfetched SVN revisions may also be tied to particular
git commits with the following syntax:
+------------------------------------------------
svn_revision_number=git_commit_sha1
+------------------------------------------------
-This allows you to tie unfetched SVN revision 375 to your current HEAD::
+This allows you to tie unfetched SVN revision 375 to your current HEAD:
- `git-svn fetch 375=$(git-rev-parse HEAD)`
+------------------------------------------------
+ git-svn fetch 375=$(git-rev-parse HEAD)
+------------------------------------------------
Advanced Example: Tracking a Reorganized Repository
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -310,6 +380,10 @@ the possible corner cases (git doesn't do it, either). Renamed and
copied files are fully supported if they're similar enough for git to
detect them.
+SEE ALSO
+--------
+gitlink:git-rebase[1]
+
Author
------
Written by Eric Wong <normalperson@yhbt.net>.
diff --git a/Documentation/git-update-index.txt b/Documentation/git-update-index.txt
index 3ae6e7457..41bb7e12e 100644
--- a/Documentation/git-update-index.txt
+++ b/Documentation/git-update-index.txt
@@ -15,7 +15,7 @@ SYNOPSIS
[--cacheinfo <mode> <object> <file>]\*
[--chmod=(+|-)x]
[--assume-unchanged | --no-assume-unchanged]
- [--really-refresh] [--unresolve] [--again]
+ [--really-refresh] [--unresolve] [--again | -g]
[--info-only] [--index-info]
[-z] [--stdin]
[--verbose]
@@ -80,7 +80,7 @@ OPTIONS
filesystem that has very slow lstat(2) system call
(e.g. cifs).
---again::
+--again, -g::
Runs `git-update-index` itself on the paths whose index
entries are different from those from the `HEAD` commit.
diff --git a/Documentation/git.txt b/Documentation/git.txt
index 3de5fa9c8..a9c87e38d 100644
--- a/Documentation/git.txt
+++ b/Documentation/git.txt
@@ -8,8 +8,9 @@ git - the stupid content tracker
SYNOPSIS
--------
+[verse]
'git' [--version] [--exec-path[=GIT_EXEC_PATH]] [-p|--paginate]
- [--bare] [--git-dir=GIT_DIR] [--help] COMMAND [ARGS]
+ [--bare] [--git-dir=GIT_DIR] [--help] COMMAND [ARGS]
DESCRIPTION
-----------
diff --git a/Documentation/gitk.txt b/Documentation/gitk.txt
index cb482bf98..23be0050b 100644
--- a/Documentation/gitk.txt
+++ b/Documentation/gitk.txt
@@ -3,26 +3,52 @@ gitk(1)
NAME
----
-gitk - Some git command not yet documented.
-
+gitk - git repository browser
SYNOPSIS
--------
-'gitk' [ --option ] <args>...
+'gitk' [<option>...] [<revs>] [--] [<path>...]
DESCRIPTION
-----------
-Does something not yet documented.
+Displays changes in a repository or a selected set of commits. This includes
+visualizing the commit graph, showing information related to each commit, and
+the files in the trees of each revision.
+Historically, gitk was the first repository browser. It's written in tcl/tk
+and started off in a separate repository but was later merged into the main
+git repository.
OPTIONS
-------
---option::
- Some option not yet documented.
+To control which revisions to shown, the command takes options applicable to
+the gitlink:git-rev-list[1] command. This manual page describes only the most
+frequently used options.
+
+-n <number>, --max-count=<number>::
+
+ Limits the number of commits to show.
+
+--since=<date>::
+
+ Show commits more recent than a specific date.
+
+--until=<date>::
+
+ Show commits older than a specific date.
-<args>...::
- Some argument not yet documented.
+<revs>::
+ Limit the revisions to show. This can be either a single revision
+ meaning show from the given revision and back, or it can be a range in
+ the form "'<from>'..'<to>'" to show all revisions between '<from>' and
+ back to '<to>'. Note, more advanced revision selection can be applied.
+
+<path>::
+
+ Limit commits to the ones touching files in the given paths. Note, to
+ avoid ambiguity wrt. revision names use "--" to separate the paths
+ from any preceeding options.
Examples
--------
@@ -37,13 +63,27 @@ gitk --since="2 weeks ago" \-- gitk::
The "--" is necessary to avoid confusion with the *branch* named
'gitk'
+See Also
+--------
+'qgit(1)'::
+ A repository browser written in C++ using Qt.
+
+'gitview(1)'::
+ A repository browser written in Python using Gtk. It's based on
+ 'bzrk(1)' and distributed in the contrib area of the git repository.
+
+'tig(1)'::
+ A minimal repository browser and git tool output highlighter written
+ in C using Ncurses.
+
Author
------
-Written by Paul Mackerras <paulus@samba.org>
+Written by Paul Mackerras <paulus@samba.org>.
Documentation
--------------
-Documentation by Junio C Hamano and the git-list <git@vger.kernel.org>.
+Documentation by Junio C Hamano, Jonas Fonseca, and the git-list
+<git@vger.kernel.org>.
GIT
---
diff --git a/Makefile b/Makefile
index 23cd8a017..b15b420ea 100644
--- a/Makefile
+++ b/Makefile
@@ -248,6 +248,7 @@ LIB_OBJS = \
server-info.o setup.o sha1_file.o sha1_name.o strbuf.o \
tag.o tree.o usage.o config.o environment.o ctype.o copy.o \
fetch-clone.o revision.o pager.o tree-walk.o xdiff-interface.o \
+ write_or_die.o \
alloc.o merge-file.o path-list.o help.o unpack-trees.o $(DIFF_OBJS)
BUILTIN_OBJS = \
diff --git a/blame.c b/blame.c
index c253b9ca4..8968046b0 100644
--- a/blame.c
+++ b/blame.c
@@ -165,7 +165,7 @@ static int get_blob_sha1(struct tree *t, const char *pathname,
blame_file = pathname;
pathspec[0] = pathname;
pathspec[1] = NULL;
- memset(blob_sha1, 0, sizeof(blob_sha1));
+ hashclr(blob_sha1);
read_tree_recursive(t, "", 0, 0, pathspec, get_blob_sha1_internal);
for (i = 0; i < 20; i++) {
@@ -176,7 +176,7 @@ static int get_blob_sha1(struct tree *t, const char *pathname,
if (i == 20)
return -1;
- memcpy(sha1, blob_sha1, 20);
+ hashcpy(sha1, blob_sha1);
return 0;
}
@@ -191,7 +191,7 @@ static int get_blob_sha1_internal(const unsigned char *sha1, const char *base,
strcmp(blame_file + baselen, pathname))
return -1;
- memcpy(blob_sha1, sha1, 20);
+ hashcpy(blob_sha1, sha1);
return -1;
}
diff --git a/builtin-apply.c b/builtin-apply.c
index 4f0eef0ac..f8f5eebd2 100644
--- a/builtin-apply.c
+++ b/builtin-apply.c
@@ -606,9 +606,7 @@ static char *git_header_name(char *line, int llen)
* form.
*/
for (len = 0 ; ; len++) {
- char c = name[len];
-
- switch (c) {
+ switch (name[len]) {
default:
continue;
case '\n':
@@ -1907,13 +1905,13 @@ static int check_patch(struct patch *patch, struct patch *prev_patch)
static int check_patch_list(struct patch *patch)
{
struct patch *prev_patch = NULL;
- int error = 0;
+ int err = 0;
for (prev_patch = NULL; patch ; patch = patch->next) {
- error |= check_patch(patch, prev_patch);
+ err |= check_patch(patch, prev_patch);
prev_patch = patch;
}
- return error;
+ return err;
}
static void show_index_list(struct patch *list)
diff --git a/builtin-cat-file.c b/builtin-cat-file.c
index df009ade7..7a6fa56e9 100644
--- a/builtin-cat-file.c
+++ b/builtin-cat-file.c
@@ -9,23 +9,6 @@
#include "tree.h"
#include "builtin.h"
-static void flush_buffer(const char *buf, unsigned long size)
-{
- while (size > 0) {
- long ret = xwrite(1, buf, size);
- if (ret < 0) {
- /* Ignore epipe */
- if (errno == EPIPE)
- break;
- die("git-cat-file: %s", strerror(errno));
- } else if (!ret) {
- die("git-cat-file: disk full?");
- }
- size -= ret;
- buf += ret;
- }
-}
-
static void pprint_tag(const unsigned char *sha1, const char *buf, unsigned long size)
{
/* the parser in tag.c is useless here. */
@@ -42,7 +25,7 @@ static void pprint_tag(const unsigned char *sha1, const char *buf, unsigned long
/* Found the tagger line. Copy out the contents
* of the buffer so far.
*/
- flush_buffer(buf, cp - buf);
+ write_or_die(1, buf, cp - buf);
/*
* Do something intelligent, like pretty-printing
@@ -61,18 +44,18 @@ static void pprint_tag(const unsigned char *sha1, const char *buf, unsigned long
sp++;
if (sp == cp) {
/* give up */
- flush_buffer(tagger,
+ write_or_die(1, tagger,
cp - tagger);
break;
}
while (sp < cp &&
!('0' <= *sp && *sp <= '9'))
sp++;
- flush_buffer(tagger, sp - tagger);
+ write_or_die(1, tagger, sp - tagger);
date = strtoul(sp, &ep, 10);
tz = strtol(ep, NULL, 10);
sp = show_date(date, tz);
- flush_buffer(sp, strlen(sp));
+ write_or_die(1, sp, strlen(sp));
xwrite(1, "\n", 1);
break;
}
@@ -90,7 +73,7 @@ static void pprint_tag(const unsigned char *sha1, const char *buf, unsigned long
* remainder as is.
*/
if (cp < endp)
- flush_buffer(cp, endp - cp);
+ write_or_die(1, cp, endp - cp);
}
int cmd_cat_file(int argc, const char **argv, const char *prefix)
@@ -162,6 +145,6 @@ int cmd_cat_file(int argc, const char **argv, const char *prefix)
if (!buf)
die("git-cat-file %s: bad file", argv[2]);
- flush_buffer(buf, size);
+ write_or_die(1, buf, size);
return 0;
}
diff --git a/builtin-commit-tree.c b/builtin-commit-tree.c
index 9c9879667..e2e690a1a 100644
--- a/builtin-commit-tree.c
+++ b/builtin-commit-tree.c
@@ -69,7 +69,7 @@ static int new_parent(int idx)
int i;
unsigned char *sha1 = parent_sha1[idx];
for (i = 0; i < idx; i++) {
- if (!memcmp(parent_sha1[i], sha1, 20)) {
+ if (!hashcmp(parent_sha1[i], sha1)) {
error("duplicate parent %s ignored", sha1_to_hex(sha1));
return 0;
}
diff --git a/builtin-diff-stages.c b/builtin-diff-stages.c
index 5960e0899..70bb89808 100644
--- a/builtin-diff-stages.c
+++ b/builtin-diff-stages.c
@@ -46,7 +46,7 @@ static void diff_stages(int stage1, int stage2, const char **pathspec)
else if (!two)
diff_addremove(&diff_options, '-', ntohl(one->ce_mode),
one->sha1, name, NULL);
- else if (memcmp(one->sha1, two->sha1, 20) ||
+ else if (hashcmp(one->sha1, two->sha1) ||
(one->ce_mode != two->ce_mode) ||
diff_options.find_copies_harder)
diff_change(&diff_options,
diff --git a/builtin-diff.c b/builtin-diff.c
index 40e5c96f3..a6590205e 100644
--- a/builtin-diff.c
+++ b/builtin-diff.c
@@ -69,7 +69,7 @@ static void stuff_change(struct diff_options *opt,
struct diff_filespec *one, *two;
if (!is_null_sha1(old_sha1) && !is_null_sha1(new_sha1) &&
- !memcmp(old_sha1, new_sha1, 20))
+ !hashcmp(old_sha1, new_sha1))
return;
if (opt->reverse_diff) {
@@ -192,7 +192,7 @@ static int builtin_diff_combined(struct rev_info *revs,
parent = xmalloc(ents * sizeof(*parent));
/* Again, the revs are all reverse */
for (i = 0; i < ents; i++)
- memcpy(parent + i, ent[ents - 1 - i].item->sha1, 20);
+ hashcpy((unsigned char*)parent + i, ent[ents - 1 - i].item->sha1);
diff_tree_combined(parent[0], parent + 1, ents - 1,
revs->dense_combined_merges, revs);
return 0;
@@ -290,7 +290,7 @@ int cmd_diff(int argc, const char **argv, const char *prefix)
if (obj->type == OBJ_BLOB) {
if (2 <= blobs)
die("more than two blobs given: '%s'", name);
- memcpy(blob[blobs].sha1, obj->sha1, 20);
+ hashcpy(blob[blobs].sha1, obj->sha1);
blob[blobs].name = name;
blobs++;
continue;
diff --git a/builtin-grep.c b/builtin-grep.c
index 0bd517b26..8213ce240 100644
--- a/builtin-grep.c
+++ b/builtin-grep.c
@@ -293,9 +293,6 @@ static void compile_patterns(struct grep_opt *opt)
*/
p = opt->pattern_list;
opt->pattern_expression = compile_pattern_expr(&p);
-#if DEBUG
- dump_pattern_exp(opt->pattern_expression, 0);
-#endif
if (p)
die("incomplete pattern expression: %s", p->pattern);
}
diff --git a/builtin-mv.c b/builtin-mv.c
index c0c8764f7..fd1e52098 100644
--- a/builtin-mv.c
+++ b/builtin-mv.c
@@ -26,7 +26,7 @@ static const char **copy_pathspec(const char *prefix, const char **pathspec,
if (length > 0 && result[i][length - 1] == '/') {
char *without_slash = xmalloc(length);
memcpy(without_slash, result[i], length - 1);
- without_slash[length] = '\0';
+ without_slash[length - 1] = '\0';
result[i] = without_slash;
}
if (base_name) {
@@ -114,7 +114,10 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
modes = xcalloc(count, sizeof(enum update_mode));
dest_path = copy_pathspec(prefix, argv + argc - 1, 1, 0);
- if (!lstat(dest_path[0], &st) &&
+ if (dest_path[0][0] == '\0')
+ /* special case: "." was normalized to "" */
+ destination = copy_pathspec(dest_path[0], argv + i, count, 1);
+ else if (!lstat(dest_path[0], &st) &&
S_ISDIR(st.st_mode)) {
dest_path[0] = add_slash(dest_path[0]);
destination = copy_pathspec(dest_path[0], argv + i, count, 1);
@@ -126,48 +129,43 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
/* Checking */
for (i = 0; i < count; i++) {
- int length;
+ const char *src = source[i], *dst = destination[i];
+ int length, src_is_dir;
const char *bad = NULL;
if (show_only)
- printf("Checking rename of '%s' to '%s'\n",
- source[i], destination[i]);
+ printf("Checking rename of '%s' to '%s'\n", src, dst);
- if (lstat(source[i], &st) < 0)
+ length = strlen(src);
+ if (lstat(src, &st) < 0)
bad = "bad source";
-
- if (!bad &&
- (length = strlen(source[i])) >= 0 &&
- !strncmp(destination[i], source[i], length) &&
- (destination[i][length] == 0 || destination[i][length] == '/'))
+ else if (!strncmp(src, dst, length) &&
+ (dst[length] == 0 || dst[length] == '/')) {
bad = "can not move directory into itself";
-
- if (S_ISDIR(st.st_mode)) {
- const char *dir = source[i], *dest_dir = destination[i];
- int first, last, len = strlen(dir);
-
- if (lstat(dest_dir, &st) == 0) {
- bad = "cannot move directory over file";
- goto next;
- }
+ } else if ((src_is_dir = S_ISDIR(st.st_mode))
+ && lstat(dst, &st) == 0)
+ bad = "cannot move directory over file";
+ else if (src_is_dir) {
+ int first, last;
modes[i] = WORKING_DIRECTORY;
- first = cache_name_pos(source[i], len);
+ first = cache_name_pos(src, length);
if (first >= 0)
- die ("Huh? %s/ is in index?", dir);
+ die ("Huh? %s/ is in index?", src);
first = -1 - first;
for (last = first; last < active_nr; last++) {
const char *path = active_cache[last]->name;
- if (strncmp(path, dir, len) || path[len] != '/')
+ if (strncmp(path, src, length)
+ || path[length] != '/')
break;
}
if (last - first < 1)
bad = "source directory is empty";
- else if (!bad) {
- int j, dst_len = strlen(dest_dir);
+ else {
+ int j, dst_len;
if (last - first > 0) {
source = realloc(source,
@@ -181,24 +179,21 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
* sizeof(enum update_mode));
}
- dest_dir = add_slash(dest_dir);
+ dst = add_slash(dst);
+ dst_len = strlen(dst) - 1;
for (j = 0; j < last - first; j++) {
const char *path =
active_cache[first + j]->name;
source[count + j] = path;
destination[count + j] =
- prefix_path(dest_dir, dst_len,
- path + len);
+ prefix_path(dst, dst_len,
+ path + length);
modes[count + j] = INDEX;
}
count += last - first;
}
-
- goto next;
- }
-
- if (!bad && lstat(destination[i], &st) == 0) {
+ } else if (lstat(dst, &st) == 0) {
bad = "destination exists";
if (force) {
/*
@@ -210,24 +205,17 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
" will overwrite!\n",
bad);
bad = NULL;
- path_list_insert(destination[i],
- &overwritten);
+ path_list_insert(dst, &overwritten);
} else
bad = "Cannot overwrite";
}
- }
-
- if (!bad && cache_name_pos(source[i], strlen(source[i])) < 0)
+ } else if (cache_name_pos(src, length) < 0)
bad = "not under version control";
+ else if (path_list_has_path(&src_for_dst, dst))
+ bad = "multiple sources for the same target";
+ else
+ path_list_insert(dst, &src_for_dst);
- if (!bad) {
- if (path_list_has_path(&src_for_dst, destination[i]))
- bad = "multiple sources for the same target";
- else
- path_list_insert(destination[i], &src_for_dst);
- }
-
-next:
if (bad) {
if (ignore_errors) {
if (--count > 0) {
@@ -239,33 +227,32 @@ next:
}
} else
die ("%s, source=%s, destination=%s",
- bad, source[i], destination[i]);
+ bad, src, dst);
}
}
for (i = 0; i < count; i++) {
+ const char *src = source[i], *dst = destination[i];
+ enum update_mode mode = modes[i];
if (show_only || verbose)
- printf("Renaming %s to %s\n",
- source[i], destination[i]);
- if (!show_only && modes[i] != INDEX &&
- rename(source[i], destination[i]) < 0 &&
- !ignore_errors)
- die ("renaming %s failed: %s",
- source[i], strerror(errno));
-
- if (modes[i] == WORKING_DIRECTORY)
+ printf("Renaming %s to %s\n", src, dst);
+ if (!show_only && mode != INDEX &&
+ rename(src, dst) < 0 && !ignore_errors)
+ die ("renaming %s failed: %s", src, strerror(errno));
+
+ if (mode == WORKING_DIRECTORY)
continue;
- if (cache_name_pos(source[i], strlen(source[i])) >= 0) {
- path_list_insert(source[i], &deleted);
+ if (cache_name_pos(src, strlen(src)) >= 0) {
+ path_list_insert(src, &deleted);
/* destination can be a directory with 1 file inside */
- if (path_list_has_path(&overwritten, destination[i]))
- path_list_insert(destination[i], &changed);
+ if (path_list_has_path(&overwritten, dst))
+ path_list_insert(dst, &changed);
else
- path_list_insert(destination[i], &added);
+ path_list_insert(dst, &added);
} else
- path_list_insert(destination[i], &added);
+ path_list_insert(dst, &added);
}
if (show_only) {
@@ -275,10 +262,10 @@ next:
} else {
for (i = 0; i < changed.nr; i++) {
const char *path = changed.items[i].path;
- int i = cache_name_pos(path, strlen(path));
- struct cache_entry *ce = active_cache[i];
+ int j = cache_name_pos(path, strlen(path));
+ struct cache_entry *ce = active_cache[j];
- if (i < 0)
+ if (j < 0)
die ("Huh? Cache entry for %s unknown?", path);
refresh_cache_entry(ce, 0);
}
diff --git a/builtin-pack-objects.c b/builtin-pack-objects.c
index 448461bc4..46f524dfc 100644
--- a/builtin-pack-objects.c
+++ b/builtin-pack-objects.c
@@ -441,7 +441,7 @@ static int locate_object_entry_hash(const unsigned char *sha1)
memcpy(&ui, sha1, sizeof(unsigned int));
i = ui % object_ix_hashsz;
while (0 < object_ix[i]) {
- if (!memcmp(sha1, objects[object_ix[i]-1].sha1, 20))
+ if (!hashcmp(sha1, objects[object_ix[i] - 1].sha1))
return i;
if (++i == object_ix_hashsz)
i = 0;
@@ -534,7 +534,7 @@ static int add_object_entry(const unsigned char *sha1, unsigned hash, int exclud
entry = objects + idx;
nr_objects = idx + 1;
memset(entry, 0, sizeof(*entry));
- memcpy(entry->sha1, sha1, 20);
+ hashcpy(entry->sha1, sha1);
entry->hash = hash;
if (object_ix_hashsz * 3 <= nr_objects * 4)
@@ -607,7 +607,7 @@ static struct pbase_tree_cache *pbase_tree_get(const unsigned char *sha1)
*/
for (neigh = 0; neigh < 8; neigh++) {
ent = pbase_tree_cache[my_ix];
- if (ent && !memcmp(ent->sha1, sha1, 20)) {
+ if (ent && !hashcmp(ent->sha1, sha1)) {
ent->ref++;
return ent;
}
@@ -649,7 +649,7 @@ static struct pbase_tree_cache *pbase_tree_get(const unsigned char *sha1)
free(ent->tree_data);
nent = ent;
}
- memcpy(nent->sha1, sha1, 20);
+ hashcpy(nent->sha1, sha1);
nent->tree_data = data;
nent->tree_size = size;
nent->ref = 1;
@@ -789,7 +789,7 @@ static void add_preferred_base(unsigned char *sha1)
return;
for (it = pbase_tree; it; it = it->next) {
- if (!memcmp(it->pcache.sha1, tree_sha1, 20)) {
+ if (!hashcmp(it->pcache.sha1, tree_sha1)) {
free(data);
return;
}
@@ -799,7 +799,7 @@ static void add_preferred_base(unsigned char *sha1)
it->next = pbase_tree;
pbase_tree = it;
- memcpy(it->pcache.sha1, tree_sha1, 20);
+ hashcpy(it->pcache.sha1, tree_sha1);
it->pcache.tree_data = data;
it->pcache.tree_size = size;
}
@@ -931,7 +931,7 @@ static struct object_entry **create_sorted_list(entry_sort_t sort)
static int sha1_sort(const struct object_entry *a, const struct object_entry *b)
{
- return memcmp(a->sha1, b->sha1, 20);
+ return hashcmp(a->sha1, b->sha1);
}
static struct object_entry **create_final_object_list(void)
diff --git a/builtin-push.c b/builtin-push.c
index 2b5e6fa9e..ada8338cc 100644
--- a/builtin-push.c
+++ b/builtin-push.c
@@ -232,7 +232,7 @@ static int do_push(const char *repo)
common_argc = argc;
for (i = 0; i < n; i++) {
- int error;
+ int err;
int dest_argc = common_argc;
int dest_refspec_nr = refspec_nr;
const char **dest_refspec = refspec;
@@ -248,10 +248,10 @@ static int do_push(const char *repo)
while (dest_refspec_nr--)
argv[dest_argc++] = *dest_refspec++;
argv[dest_argc] = NULL;
- error = run_command_v(argc, argv);
- if (!error)
+ err = run_command_v(argc, argv);
+ if (!err)
continue;
- switch (error) {
+ switch (err) {
case -ERR_RUN_COMMAND_FORK:
die("unable to fork for %s", sender);
case -ERR_RUN_COMMAND_EXEC:
@@ -262,7 +262,7 @@ static int do_push(const char *repo)
case -ERR_RUN_COMMAND_WAITPID_NOEXIT:
die("%s died with strange error", sender);
default:
- return -error;
+ return -err;
}
}
return 0;
diff --git a/builtin-read-tree.c b/builtin-read-tree.c
index 53087faf7..c1867d2a0 100644
--- a/builtin-read-tree.c
+++ b/builtin-read-tree.c
@@ -53,7 +53,7 @@ static void prime_cache_tree_rec(struct cache_tree *it, struct tree *tree)
struct name_entry entry;
int cnt;
- memcpy(it->sha1, tree->object.sha1, 20);
+ hashcpy(it->sha1, tree->object.sha1);
desc.buf = tree->buffer;
desc.size = tree->size;
cnt = 0;
diff --git a/builtin-show-branch.c b/builtin-show-branch.c
index 95fbf77fa..18786f88e 100644
--- a/builtin-show-branch.c
+++ b/builtin-show-branch.c
@@ -378,7 +378,7 @@ static int append_head_ref(const char *refname, const unsigned char *sha1)
/* If both heads/foo and tags/foo exists, get_sha1 would
* get confused.
*/
- if (get_sha1(refname + ofs, tmp) || memcmp(tmp, sha1, 20))
+ if (get_sha1(refname + ofs, tmp) || hashcmp(tmp, sha1))
ofs = 5;
return append_ref(refname + ofs, sha1);
}
@@ -442,7 +442,7 @@ static int rev_is_head(char *head_path, int headlen, char *name,
{
int namelen;
if ((!head_path[0]) ||
- (head_sha1 && sha1 && memcmp(head_sha1, sha1, 20)))
+ (head_sha1 && sha1 && hashcmp(head_sha1, sha1)))
return 0;
namelen = strlen(name);
if ((headlen < namelen) ||
diff --git a/builtin-tar-tree.c b/builtin-tar-tree.c
index 215892b69..61a413590 100644
--- a/builtin-tar-tree.c
+++ b/builtin-tar-tree.c
@@ -14,7 +14,7 @@
#define BLOCKSIZE (RECORDSIZE * 20)
static const char tar_tree_usage[] =
-"git-tar-tree [--remote=<repo>] <ent> [basedir]";
+"git-tar-tree [--remote=<repo>] <tree-ish> [basedir]";
static char block[BLOCKSIZE];
static unsigned long offset;
@@ -22,30 +22,11 @@ static unsigned long offset;
static time_t archive_time;
static int tar_umask;
-/* tries hard to write, either succeeds or dies in the attempt */
-static void reliable_write(const void *data, unsigned long size)
-{
- const char *buf = data;
-
- while (size > 0) {
- long ret = xwrite(1, buf, size);
- if (ret < 0) {
- if (errno == EPIPE)
- exit(0);
- die("git-tar-tree: %s", strerror(errno));
- } else if (!ret) {
- die("git-tar-tree: disk full?");
- }
- size -= ret;
- buf += ret;
- }
-}
-
/* writes out the whole block, but only if it is full */
static void write_if_needed(void)
{
if (offset == BLOCKSIZE) {
- reliable_write(block, BLOCKSIZE);
+ write_or_die(1, block, BLOCKSIZE);
offset = 0;
}
}
@@ -70,7 +51,7 @@ static void write_blocked(const void *data, unsigned long size)
write_if_needed();
}
while (size >= BLOCKSIZE) {
- reliable_write(buf, BLOCKSIZE);
+ write_or_die(1, buf, BLOCKSIZE);
size -= BLOCKSIZE;
buf += BLOCKSIZE;
}
@@ -94,10 +75,10 @@ static void write_trailer(void)
{
int tail = BLOCKSIZE - offset;
memset(block + offset, 0, tail);
- reliable_write(block, BLOCKSIZE);
+ write_or_die(1, block, BLOCKSIZE);
if (tail < 2 * RECORDSIZE) {
memset(block, 0, offset);
- reliable_write(block, BLOCKSIZE);
+ write_or_die(1, block, BLOCKSIZE);
}
}
@@ -294,7 +275,7 @@ static void traverse_tree(struct tree_desc *tree, struct strbuf *path)
}
}
-int git_tar_config(const char *var, const char *value)
+static int git_tar_config(const char *var, const char *value)
{
if (!strcmp(var, "tar.umask")) {
if (!strcmp(value, "user")) {
diff --git a/builtin-unpack-objects.c b/builtin-unpack-objects.c
index 63f4b8e45..ca0ebc258 100644
--- a/builtin-unpack-objects.c
+++ b/builtin-unpack-objects.c
@@ -95,7 +95,7 @@ static void add_delta_to_list(unsigned char *base_sha1, void *delta, unsigned lo
{
struct delta_info *info = xmalloc(sizeof(*info));
- memcpy(info->base_sha1, base_sha1, 20);
+ hashcpy(info->base_sha1, base_sha1);
info->size = size;
info->delta = delta;
info->next = delta_list;
@@ -136,7 +136,7 @@ static void added_object(unsigned char *sha1, const char *type, void *data, unsi
struct delta_info *info;
while ((info = *p) != NULL) {
- if (!memcmp(info->base_sha1, sha1, 20)) {
+ if (!hashcmp(info->base_sha1, sha1)) {
*p = info->next;
p = &delta_list;
resolve_delta(type, data, size, info->delta, info->size);
@@ -173,7 +173,7 @@ static int unpack_delta_entry(unsigned long delta_size)
unsigned char base_sha1[20];
int result;
- memcpy(base_sha1, fill(20), 20);
+ hashcpy(base_sha1, fill(20));
use(20);
delta_data = get_data(delta_size);
@@ -292,7 +292,7 @@ int cmd_unpack_objects(int argc, const char **argv, const char *prefix)
unpack_all();
SHA1_Update(&ctx, buffer, offset);
SHA1_Final(sha1, &ctx);
- if (memcmp(fill(20), sha1, 20))
+ if (hashcmp(fill(20), sha1))
die("final sha1 did not match");
use(20);
diff --git a/builtin-update-index.c b/builtin-update-index.c
index 9f0cf28ba..0620e779b 100644
--- a/builtin-update-index.c
+++ b/builtin-update-index.c
@@ -142,7 +142,7 @@ static int add_cacheinfo(unsigned int mode, const unsigned char *sha1,
size = cache_entry_size(len);
ce = xcalloc(1, size);
- memcpy(ce->sha1, sha1, 20);
+ hashcpy(ce->sha1, sha1);
memcpy(ce->name, path, len);
ce->ce_flags = create_ce_flags(len, stage);
ce->ce_mode = create_ce_mode(mode);
@@ -306,7 +306,7 @@ static void read_index_info(int line_termination)
}
static const char update_index_usage[] =
-"git-update-index [-q] [--add] [--replace] [--remove] [--unmerged] [--refresh] [--really-refresh] [--cacheinfo] [--chmod=(+|-)x] [--assume-unchanged] [--info-only] [--force-remove] [--stdin] [--index-info] [--unresolve] [--again] [--ignore-missing] [-z] [--verbose] [--] <file>...";
+"git-update-index [-q] [--add] [--replace] [--remove] [--unmerged] [--refresh] [--really-refresh] [--cacheinfo] [--chmod=(+|-)x] [--assume-unchanged] [--info-only] [--force-remove] [--stdin] [--index-info] [--unresolve] [--again | -g] [--ignore-missing] [-z] [--verbose] [--] <file>...";
static unsigned char head_sha1[20];
static unsigned char merge_head_sha1[20];
@@ -333,7 +333,7 @@ static struct cache_entry *read_one_ent(const char *which,
size = cache_entry_size(namelen);
ce = xcalloc(1, size);
- memcpy(ce->sha1, sha1, 20);
+ hashcpy(ce->sha1, sha1);
memcpy(ce->name, path, namelen);
ce->ce_flags = create_ce_flags(namelen, stage);
ce->ce_mode = create_ce_mode(mode);
@@ -378,7 +378,7 @@ static int unresolve_one(const char *path)
ret = -1;
goto free_return;
}
- if (!memcmp(ce_2->sha1, ce_3->sha1, 20) &&
+ if (!hashcmp(ce_2->sha1, ce_3->sha1) &&
ce_2->ce_mode == ce_3->ce_mode) {
fprintf(stderr, "%s: identical in both, skipping.\n",
path);
@@ -460,7 +460,7 @@ static int do_reupdate(int ac, const char **av,
old = read_one_ent(NULL, head_sha1,
ce->name, ce_namelen(ce), 0);
if (old && ce->ce_mode == old->ce_mode &&
- !memcmp(ce->sha1, old->sha1, 20)) {
+ !hashcmp(ce->sha1, old->sha1)) {
free(old);
continue; /* unchanged */
}
@@ -595,7 +595,7 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)
active_cache_changed = 0;
goto finish;
}
- if (!strcmp(path, "--again")) {
+ if (!strcmp(path, "--again") || !strcmp(path, "-g")) {
has_errors = do_reupdate(argc - i, argv + i,
prefix, prefix_length);
if (has_errors)
diff --git a/builtin-update-ref.c b/builtin-update-ref.c
index 5bd71825f..90a3da53a 100644
--- a/builtin-update-ref.c
+++ b/builtin-update-ref.c
@@ -44,7 +44,7 @@ int cmd_update_ref(int argc, const char **argv, const char *prefix)
if (get_sha1(value, sha1))
die("%s: not a valid SHA1", value);
- memset(oldsha1, 0, 20);
+ hashclr(oldsha1);
if (oldval && get_sha1(oldval, oldsha1))
die("%s: not a valid old SHA1", oldval);
diff --git a/builtin-write-tree.c b/builtin-write-tree.c
index ca06149f1..50670dc7b 100644
--- a/builtin-write-tree.c
+++ b/builtin-write-tree.c
@@ -50,10 +50,10 @@ int write_tree(unsigned char *sha1, int missing_ok, const char *prefix)
if (prefix) {
struct cache_tree *subtree =
cache_tree_find(active_cache_tree, prefix);
- memcpy(sha1, subtree->sha1, 20);
+ hashcpy(sha1, subtree->sha1);
}
else
- memcpy(sha1, active_cache_tree->sha1, 20);
+ hashcpy(sha1, active_cache_tree->sha1);
rollback_lock_file(lock_file);
diff --git a/cache-tree.c b/cache-tree.c
index d9f7e1e3d..323c68a67 100644
--- a/cache-tree.c
+++ b/cache-tree.c
@@ -335,7 +335,7 @@ static int update_one(struct cache_tree *it,
offset += sprintf(buffer + offset,
"%o %.*s", mode, entlen, path + baselen);
buffer[offset++] = 0;
- memcpy(buffer + offset, sha1, 20);
+ hashcpy((unsigned char*)buffer + offset, sha1);
offset += 20;
#if DEBUG
@@ -412,7 +412,7 @@ static void *write_one(struct cache_tree *it,
#endif
if (0 <= it->entry_count) {
- memcpy(buffer + *offset, it->sha1, 20);
+ hashcpy((unsigned char*)buffer + *offset, it->sha1);
*offset += 20;
}
for (i = 0; i < it->subtree_nr; i++) {
@@ -478,7 +478,7 @@ static struct cache_tree *read_one(const char **buffer, unsigned long *size_p)
if (0 <= it->entry_count) {
if (size < 20)
goto free_return;
- memcpy(it->sha1, buf, 20);
+ hashcpy(it->sha1, (unsigned char*)buf);
buf += 20;
size -= 20;
}
diff --git a/cache.h b/cache.h
index c7382996f..1f212d77a 100644
--- a/cache.h
+++ b/cache.h
@@ -123,7 +123,7 @@ extern int cache_errno;
#define INDEX_ENVIRONMENT "GIT_INDEX_FILE"
#define GRAFT_ENVIRONMENT "GIT_GRAFT_FILE"
-extern char *get_git_dir(void);
+extern const char *get_git_dir(void);
extern char *get_object_directory(void);
extern char *get_refs_directory(void);
extern char *get_index_file(void);
@@ -214,6 +214,18 @@ static inline int is_null_sha1(const unsigned char *sha1)
{
return !memcmp(sha1, null_sha1, 20);
}
+static inline int hashcmp(const unsigned char *sha1, const unsigned char *sha2)
+{
+ return memcmp(sha1, sha2, 20);
+}
+static inline void hashcpy(unsigned char *sha_dst, const unsigned char *sha_src)
+{
+ memcpy(sha_dst, sha_src, 20);
+}
+static inline void hashclr(unsigned char *hash)
+{
+ memset(hash, 0, 20);
+}
int git_mkstemp(char *path, size_t n, const char *template);
@@ -384,6 +396,7 @@ extern char git_default_name[MAX_GITNAME];
extern char git_commit_encoding[MAX_ENCODING_LENGTH];
extern int copy_fd(int ifd, int ofd);
+extern void write_or_die(int fd, const void *buf, size_t count);
/* Finish off pack transfer receiving end */
extern int receive_unpack_pack(int fd[2], const char *me, int quiet, int);
diff --git a/combine-diff.c b/combine-diff.c
index ce063b4ff..46d9121ba 100644
--- a/combine-diff.c
+++ b/combine-diff.c
@@ -31,9 +31,9 @@ static struct combine_diff_path *intersect_paths(struct combine_diff_path *curr,
memset(p->parent, 0,
sizeof(p->parent[0]) * num_parent);
- memcpy(p->sha1, q->queue[i]->two->sha1, 20);
+ hashcpy(p->sha1, q->queue[i]->two->sha1);
p->mode = q->queue[i]->two->mode;
- memcpy(p->parent[n].sha1, q->queue[i]->one->sha1, 20);
+ hashcpy(p->parent[n].sha1, q->queue[i]->one->sha1);
p->parent[n].mode = q->queue[i]->one->mode;
p->parent[n].status = q->queue[i]->status;
*tail = p;
@@ -56,8 +56,7 @@ static struct combine_diff_path *intersect_paths(struct combine_diff_path *curr,
len = strlen(path);
if (len == p->len && !memcmp(path, p->path, len)) {
found = 1;
- memcpy(p->parent[n].sha1,
- q->queue[i]->one->sha1, 20);
+ hashcpy(p->parent[n].sha1, q->queue[i]->one->sha1);
p->parent[n].mode = q->queue[i]->one->mode;
p->parent[n].status = q->queue[i]->status;
break;
@@ -688,8 +687,8 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
for (i = 0; i < num_parent; i++) {
int j;
for (j = 0; j < i; j++) {
- if (!memcmp(elem->parent[i].sha1,
- elem->parent[j].sha1, 20)) {
+ if (!hashcmp(elem->parent[i].sha1,
+ elem->parent[j].sha1)) {
reuse_combine_diff(sline, cnt, i, j);
break;
}
@@ -927,6 +926,7 @@ void diff_tree_combined_merge(const unsigned char *sha1,
for (parents = commit->parents, num_parent = 0;
parents;
parents = parents->next, num_parent++)
- memcpy(parent + num_parent, parents->item->object.sha1, 20);
+ hashcpy((unsigned char*)(parent + num_parent),
+ parents->item->object.sha1);
diff_tree_combined(sha1, parent, num_parent, dense, rev);
}
diff --git a/commit.c b/commit.c
index 972d1b70c..00bc3de22 100644
--- a/commit.c
+++ b/commit.c
@@ -7,15 +7,15 @@ int save_commit_buffer = 1;
struct sort_node
{
/*
- * the number of children of the associated commit
- * that also occur in the list being sorted.
- */
+ * the number of children of the associated commit
+ * that also occur in the list being sorted.
+ */
unsigned int indegree;
/*
- * reference to original list item that we will re-use
- * on output.
- */
+ * reference to original list item that we will re-use
+ * on output.
+ */
struct commit_list * list_item;
};
@@ -123,7 +123,7 @@ static int commit_graft_pos(const unsigned char *sha1)
while (lo < hi) {
int mi = (lo + hi) / 2;
struct commit_graft *graft = commit_graft[mi];
- int cmp = memcmp(sha1, graft->sha1, 20);
+ int cmp = hashcmp(sha1, graft->sha1);
if (!cmp)
return mi;
if (cmp < 0)
diff --git a/connect.c b/connect.c
index 7a6a73f2a..e501ccce2 100644
--- a/connect.c
+++ b/connect.c
@@ -77,7 +77,7 @@ struct ref **get_remote_heads(int in, struct ref **list,
if (nr_match && !path_match(name, nr_match, match))
continue;
ref = xcalloc(1, sizeof(*ref) + len - 40);
- memcpy(ref->old_sha1, old_sha1, 20);
+ hashcpy(ref->old_sha1, old_sha1);
memcpy(ref->name, buffer + 41, len - 40);
*list = ref;
list = &ref->next;
@@ -208,7 +208,7 @@ static struct ref *try_explicit_object_name(const char *name)
len = strlen(name) + 1;
ref = xcalloc(1, sizeof(*ref) + len);
memcpy(ref->name, name, len);
- memcpy(ref->new_sha1, sha1, 20);
+ hashcpy(ref->new_sha1, sha1);
return ref;
}
@@ -318,7 +318,7 @@ int match_refs(struct ref *src, struct ref *dst, struct ref ***dst_tail,
int len = strlen(src->name) + 1;
dst_peer = xcalloc(1, sizeof(*dst_peer) + len);
memcpy(dst_peer->name, src->name, len);
- memcpy(dst_peer->new_sha1, src->new_sha1, 20);
+ hashcpy(dst_peer->new_sha1, src->new_sha1);
link_dst_tail(dst_peer, dst_tail);
}
dst_peer->peer_ref = src;
diff --git a/contrib/gitview/gitview.txt b/contrib/gitview/gitview.txt
index 6924df286..77c29de30 100644
--- a/contrib/gitview/gitview.txt
+++ b/contrib/gitview/gitview.txt
@@ -7,40 +7,50 @@ gitview - A GTK based repository browser for git
SYNOPSIS
--------
-'gitview' [options] [args]
+'gitview' [options] [args]
DESCRIPTION
---------
-Dependencies
+Dependencies:
* Python 2.4
* PyGTK 2.8 or later
* PyCairo 1.0 or later
OPTIONS
-------
- --without-diff
- If the user doesn't want to list the commit diffs in the main window. This may speed up the repository browsing.
-
- <args>
- All the valid option for git-rev-list(1)
- Key Bindings:
- F4:
- To maximize the window
- F5:
- To reread references.
- F11:
- Full screen
- F12:
- Leave full screen
+-------
+--without-diff::
+
+ If the user doesn't want to list the commit diffs in the main window.
+ This may speed up the repository browsing.
+
+<args>::
+
+ All the valid option for gitlink:git-rev-list[1].
+
+Key Bindings
+------------
+F4::
+ To maximize the window
+
+F5::
+ To reread references.
+
+F11::
+ Full screen
+
+F12::
+ Leave full screen
EXAMPLES
-------
- gitview v2.6.12.. include/scsi drivers/scsi
- Show as the changes since version v2.6.12 that changed any file in the include/scsi
- or drivers/scsi subdirectories
+--------
+
+gitview v2.6.12.. include/scsi drivers/scsi::
+
+ Show as the changes since version v2.6.12 that changed any file in the
+ include/scsi or drivers/scsi subdirectories
- gitview --since=2.weeks.ago
- Show the changes during the last two weeks
+gitview --since=2.weeks.ago::
+ Show the changes during the last two weeks
diff --git a/convert-objects.c b/convert-objects.c
index 168771ed8..631678b08 100644
--- a/convert-objects.c
+++ b/convert-objects.c
@@ -23,7 +23,7 @@ static struct entry * convert_entry(unsigned char *sha1);
static struct entry *insert_new(unsigned char *sha1, int pos)
{
struct entry *new = xcalloc(1, sizeof(struct entry));
- memcpy(new->old_sha1, sha1, 20);
+ hashcpy(new->old_sha1, sha1);
memmove(convert + pos + 1, convert + pos, (nr_convert - pos) * sizeof(struct entry *));
convert[pos] = new;
nr_convert++;
@@ -39,7 +39,7 @@ static struct entry *lookup_entry(unsigned char *sha1)
while (low < high) {
int next = (low + high) / 2;
struct entry *n = convert[next];
- int cmp = memcmp(sha1, n->old_sha1, 20);
+ int cmp = hashcmp(sha1, n->old_sha1);
if (!cmp)
return n;
if (cmp < 0) {
@@ -54,7 +54,7 @@ static struct entry *lookup_entry(unsigned char *sha1)
static void convert_binary_sha1(void *buffer)
{
struct entry *entry = convert_entry(buffer);
- memcpy(buffer, entry->new_sha1, 20);
+ hashcpy(buffer, entry->new_sha1);
}
static void convert_ascii_sha1(void *buffer)
@@ -104,7 +104,7 @@ static int write_subdirectory(void *buffer, unsigned long size, const char *base
if (!slash) {
newlen += sprintf(new + newlen, "%o %s", mode, path);
new[newlen++] = '\0';
- memcpy(new + newlen, (char *) buffer + len - 20, 20);
+ hashcpy((unsigned char*)new + newlen, (unsigned char *) buffer + len - 20);
newlen += 20;
used += len;
diff --git a/csum-file.c b/csum-file.c
index e2278897d..b7174c6c0 100644
--- a/csum-file.c
+++ b/csum-file.c
@@ -38,7 +38,7 @@ int sha1close(struct sha1file *f, unsigned char *result, int update)
}
SHA1_Final(f->buffer, &f->ctx);
if (result)
- memcpy(result, f->buffer, 20);
+ hashcpy(result, f->buffer);
if (update)
sha1flush(f, 20);
if (close(f->fd))
diff --git a/date.c b/date.c
index 66be23ab2..d780846b6 100644
--- a/date.c
+++ b/date.c
@@ -584,10 +584,10 @@ static const char *approxidate_alpha(const char *date, struct tm *tm, int *num)
const struct typelen *tl;
const struct special *s;
const char *end = date;
- int n = 1, i;
+ int i;
- while (isalpha(*++end))
- n++;
+ while (isalpha(*++end));
+ ;
for (i = 0; i < 12; i++) {
int match = match_string(date, month_names[i]);
diff --git a/describe.c b/describe.c
index 2b9301fc1..5dd8b2e39 100644
--- a/describe.c
+++ b/describe.c
@@ -42,7 +42,7 @@ static void add_to_known_names(const char *path,
struct commit_name *name = xmalloc(sizeof(struct commit_name) + len);
name->commit = commit;
- name->prio = prio;
+ name->prio = prio;
memcpy(name->path, path, len);
idx = names;
if (idx >= allocs) {
@@ -154,7 +154,7 @@ int main(int argc, char **argv)
tags = 1;
else if (!strncmp(arg, "--abbrev=", 9)) {
abbrev = strtoul(arg + 9, NULL, 10);
- if (abbrev < MINIMUM_ABBREV || 40 <= abbrev)
+ if (abbrev < MINIMUM_ABBREV || 40 < abbrev)
abbrev = DEFAULT_ABBREV;
}
else
diff --git a/diff-delta.c b/diff-delta.c
index 7da9205a5..51e2e5617 100644
--- a/diff-delta.c
+++ b/diff-delta.c
@@ -152,7 +152,7 @@ struct delta_index * create_delta_index(const void *buf, unsigned long bufsize)
initialization in create_delta(). */
entries = (bufsize - 1) / RABIN_WINDOW;
hsize = entries / 4;
- for (i = 4; (1 << i) < hsize && i < 31; i++);
+ for (i = 4; (1u << i) < hsize && i < 31; i++);
hsize = 1 << i;
hmask = hsize - 1;
diff --git a/diff-lib.c b/diff-lib.c
index 116b5a9d6..9edfa9262 100644
--- a/diff-lib.c
+++ b/diff-lib.c
@@ -48,7 +48,7 @@ int run_diff_files(struct rev_info *revs, int silent_on_removed)
memcpy(dpath->path, ce->name, path_len);
dpath->path[path_len] = '\0';
dpath->mode = 0;
- memset(dpath->sha1, 0, 20);
+ hashclr(dpath->sha1);
memset(&(dpath->parent[0]), 0,
sizeof(struct combine_diff_parent)*5);
@@ -66,8 +66,7 @@ int run_diff_files(struct rev_info *revs, int silent_on_removed)
if (2 <= stage) {
int mode = ntohl(nce->ce_mode);
num_compare_stages++;
- memcpy(dpath->parent[stage-2].sha1,
- nce->sha1, 20);
+ hashcpy(dpath->parent[stage-2].sha1, nce->sha1);
dpath->parent[stage-2].mode =
canon_mode(mode);
dpath->parent[stage-2].status =
@@ -215,7 +214,7 @@ static int show_modified(struct rev_info *revs,
}
oldmode = old->ce_mode;
- if (mode == oldmode && !memcmp(sha1, old->sha1, 20) &&
+ if (mode == oldmode && !hashcmp(sha1, old->sha1) &&
!revs->diffopt.find_copies_harder)
return 0;
diff --git a/diff.c b/diff.c
index 7a238d023..ca171e8e6 100644
--- a/diff.c
+++ b/diff.c
@@ -1101,7 +1101,7 @@ void fill_filespec(struct diff_filespec *spec, const unsigned char *sha1,
{
if (mode) {
spec->mode = canon_mode(mode);
- memcpy(spec->sha1, sha1, 20);
+ hashcpy(spec->sha1, sha1);
spec->sha1_valid = !is_null_sha1(sha1);
}
}
@@ -1140,7 +1140,7 @@ static int work_tree_matches(const char *name, const unsigned char *sha1)
if ((lstat(name, &st) < 0) ||
!S_ISREG(st.st_mode) || /* careful! */
ce_match_stat(ce, &st, 0) ||
- memcmp(sha1, ce->sha1, 20))
+ hashcmp(sha1, ce->sha1))
return 0;
/* we return 1 only when we can stat, it is a regular file,
* stat information matches, and sha1 recorded in the cache
@@ -1168,7 +1168,7 @@ static struct sha1_size_cache *locate_size_cache(unsigned char *sha1,
while (last > first) {
int cmp, next = (last + first) >> 1;
e = sha1_size_cache[next];
- cmp = memcmp(e->sha1, sha1, 20);
+ cmp = hashcmp(e->sha1, sha1);
if (!cmp)
return e;
if (cmp < 0) {
@@ -1194,7 +1194,7 @@ static struct sha1_size_cache *locate_size_cache(unsigned char *sha1,
sizeof(*sha1_size_cache));
e = xmalloc(sizeof(struct sha1_size_cache));
sha1_size_cache[first] = e;
- memcpy(e->sha1, sha1, 20);
+ hashcpy(e->sha1, sha1);
e->size = size;
return e;
}
@@ -1516,7 +1516,7 @@ static void diff_fill_sha1_info(struct diff_filespec *one)
}
}
else
- memset(one->sha1, 0, 20);
+ hashclr(one->sha1);
}
static void run_diff(struct diff_filepair *p, struct diff_options *o)
@@ -1579,7 +1579,7 @@ static void run_diff(struct diff_filepair *p, struct diff_options *o)
;
}
- if (memcmp(one->sha1, two->sha1, 20)) {
+ if (hashcmp(one->sha1, two->sha1)) {
int abbrev = o->full_index ? 40 : DEFAULT_ABBREV;
len += snprintf(msg + len, sizeof(msg) - len,
@@ -2098,7 +2098,7 @@ int diff_unmodified_pair(struct diff_filepair *p)
* dealing with a change.
*/
if (one->sha1_valid && two->sha1_valid &&
- !memcmp(one->sha1, two->sha1, sizeof(one->sha1)))
+ !hashcmp(one->sha1, two->sha1))
return 1; /* no change */
if (!one->sha1_valid && !two->sha1_valid)
return 1; /* both look at the same file on the filesystem. */
@@ -2237,7 +2237,7 @@ static void diff_resolve_rename_copy(void)
if (!p->status)
p->status = DIFF_STATUS_RENAMED;
}
- else if (memcmp(p->one->sha1, p->two->sha1, 20) ||
+ else if (hashcmp(p->one->sha1, p->two->sha1) ||
p->one->mode != p->two->mode)
p->status = DIFF_STATUS_MODIFIED;
else {
diff --git a/diffcore-break.c b/diffcore-break.c
index ed0e14c6d..acb18db1d 100644
--- a/diffcore-break.c
+++ b/diffcore-break.c
@@ -56,7 +56,7 @@ static int should_break(struct diff_filespec *src,
return 0; /* leave symlink rename alone */
if (src->sha1_valid && dst->sha1_valid &&
- !memcmp(src->sha1, dst->sha1, 20))
+ !hashcmp(src->sha1, dst->sha1))
return 0; /* they are the same */
if (diff_populate_filespec(src, 0) || diff_populate_filespec(dst, 0))
diff --git a/diffcore-rename.c b/diffcore-rename.c
index 0ec488a90..ef239012b 100644
--- a/diffcore-rename.c
+++ b/diffcore-rename.c
@@ -101,7 +101,7 @@ static int is_exact_match(struct diff_filespec *src,
int contents_too)
{
if (src->sha1_valid && dst->sha1_valid &&
- !memcmp(src->sha1, dst->sha1, 20))
+ !hashcmp(src->sha1, dst->sha1))
return 1;
if (!contents_too)
return 0;
diff --git a/dump-cache-tree.c b/dump-cache-tree.c
index 1ccaf5177..1f73f1ea7 100644
--- a/dump-cache-tree.c
+++ b/dump-cache-tree.c
@@ -33,7 +33,7 @@ static int dump_cache_tree(struct cache_tree *it,
}
else {
dump_one(it, pfx, "");
- if (memcmp(it->sha1, ref->sha1, 20) ||
+ if (hashcmp(it->sha1, ref->sha1) ||
ref->entry_count != it->entry_count ||
ref->subtree_nr != it->subtree_nr) {
dump_one(ref, pfx, "#(ref) ");
diff --git a/environment.c b/environment.c
index e6bd0033b..5fae9ac30 100644
--- a/environment.c
+++ b/environment.c
@@ -25,8 +25,9 @@ int zlib_compression_level = Z_DEFAULT_COMPRESSION;
int pager_in_use;
int pager_use_color = 1;
-static char *git_dir, *git_object_dir, *git_index_file, *git_refs_dir,
- *git_graft_file;
+static const char *git_dir;
+static char *git_object_dir, *git_index_file, *git_refs_dir, *git_graft_file;
+
static void setup_git_env(void)
{
git_dir = getenv(GIT_DIR_ENVIRONMENT);
@@ -49,7 +50,7 @@ static void setup_git_env(void)
git_graft_file = strdup(git_path("info/grafts"));
}
-char *get_git_dir(void)
+const char *get_git_dir(void)
{
if (!git_dir)
setup_git_env();
diff --git a/fetch-pack.c b/fetch-pack.c
index e18c1489a..377feded1 100644
--- a/fetch-pack.c
+++ b/fetch-pack.c
@@ -404,7 +404,7 @@ static int everything_local(struct ref **refs, int nr_match, char **match)
continue;
}
- memcpy(ref->new_sha1, local, 20);
+ hashcpy(ref->new_sha1, local);
if (!verbose)
continue;
fprintf(stderr,
diff --git a/fetch.c b/fetch.c
index aeb6bf263..ef60b045e 100644
--- a/fetch.c
+++ b/fetch.c
@@ -84,7 +84,7 @@ static int process_commit(struct commit *commit)
if (commit->object.flags & COMPLETE)
return 0;
- memcpy(current_commit_sha1, commit->object.sha1, 20);
+ hashcpy(current_commit_sha1, commit->object.sha1);
pull_say("walk %s\n", sha1_to_hex(commit->object.sha1));
diff --git a/fsck-objects.c b/fsck-objects.c
index 31e00d84b..ae0ec8d03 100644
--- a/fsck-objects.c
+++ b/fsck-objects.c
@@ -356,7 +356,7 @@ static void add_sha1_list(unsigned char *sha1, unsigned long ino)
int nr;
entry->ino = ino;
- memcpy(entry->sha1, sha1, 20);
+ hashcpy(entry->sha1, sha1);
nr = sha1_list.nr;
if (nr == MAX_SHA1_ENTRIES) {
fsck_sha1_list();
diff --git a/git-send-email.perl b/git-send-email.perl
index a83c7e909..746c52507 100755
--- a/git-send-email.perl
+++ b/git-send-email.perl
@@ -510,7 +510,7 @@ foreach my $t (@files) {
if ($2 eq $from) {
next if ($suppress_from);
}
- else {
+ elsif ($1 eq 'From') {
$author_not_sender = $2;
}
printf("(mbox) Adding cc: %s from line '%s'\n",
diff --git a/git-svn.perl b/git-svn.perl
index 0d58bb9b3..9382a1504 100755
--- a/git-svn.perl
+++ b/git-svn.perl
@@ -51,7 +51,8 @@ my ($_revision,$_stdin,$_no_ignore_ext,$_no_stop_copy,$_help,$_rmdir,$_edit,
$_message, $_file, $_follow_parent, $_no_metadata,
$_template, $_shared, $_no_default_regex, $_no_graft_copy,
$_limit, $_verbose, $_incremental, $_oneline, $_l_fmt, $_show_commit,
- $_version, $_upgrade, $_authors, $_branch_all_refs, @_opt_m);
+ $_version, $_upgrade, $_authors, $_branch_all_refs, @_opt_m,
+ $_merge, $_strategy, $_dry_run);
my (@_branch_from, %tree_map, %users, %rusers, %equiv);
my ($_svn_co_url_revs, $_svn_pg_peg_revs);
my @repo_path_split_cache;
@@ -118,6 +119,11 @@ my %cmd = (
{ 'message|m=s' => \$_message,
'file|F=s' => \$_file,
%cmt_opts } ],
+ dcommit => [ \&dcommit, 'Commit several diffs to merge with upstream',
+ { 'merge|m|M' => \$_merge,
+ 'strategy|s=s' => \$_strategy,
+ 'dry-run|n' => \$_dry_run,
+ %cmt_opts } ],
);
my $cmd;
@@ -500,6 +506,8 @@ sub commit_lib {
my @lock = $SVN::Core::VERSION ge '1.2.0' ? (undef, 0) : ();
my $commit_msg = "$GIT_SVN_DIR/.svn-commit.tmp.$$";
+ my $repo;
+ ($repo, $SVN_PATH) = repo_path_split($SVN_URL);
set_svn_commit_env();
foreach my $c (@revs) {
my $log_msg = get_commit_message($c, $commit_msg);
@@ -508,6 +516,8 @@ sub commit_lib {
# can't track down... (it's probably in the SVN code)
defined(my $pid = open my $fh, '-|') or croak $!;
if (!$pid) {
+ $SVN_LOG = libsvn_connect($repo);
+ $SVN = libsvn_connect($repo);
my $ed = SVN::Git::Editor->new(
{ r => $r_last,
ra => $SVN,
@@ -557,6 +567,33 @@ sub commit_lib {
unlink $commit_msg;
}
+sub dcommit {
+ my $gs = "refs/remotes/$GIT_SVN";
+ chomp(my @refs = safe_qx(qw/git-rev-list --no-merges/, "$gs..HEAD"));
+ foreach my $d (reverse @refs) {
+ if ($_dry_run) {
+ print "diff-tree $d~1 $d\n";
+ } else {
+ commit_diff("$d~1", $d);
+ }
+ }
+ return if $_dry_run;
+ fetch();
+ my @diff = safe_qx(qw/git-diff-tree HEAD/, $gs);
+ my @finish;
+ if (@diff) {
+ @finish = qw/rebase/;
+ push @finish, qw/--merge/ if $_merge;
+ push @finish, "--strategy=$_strategy" if $_strategy;
+ print STDERR "W: HEAD and $gs differ, using @finish:\n", @diff;
+ } else {
+ print "No changes between current HEAD and $gs\n",
+ "Hard resetting to the latest $gs\n";
+ @finish = qw/reset --hard/;
+ }
+ sys('git', @finish, $gs);
+}
+
sub show_ignore {
$SVN_URL ||= file_to_s("$GIT_SVN_DIR/info/url");
$_use_lib ? show_ignore_lib() : show_ignore_cmd();
diff --git a/git.c b/git.c
index 930998bbe..a01d195c2 100644
--- a/git.c
+++ b/git.c
@@ -292,11 +292,11 @@ static void handle_internal_command(int argc, const char **argv, char **envp)
if (p->option & USE_PAGER)
setup_pager();
if (getenv("GIT_TRACE")) {
- int i;
+ int j;
fprintf(stderr, "trace: built-in: git");
- for (i = 0; i < argc; ++i) {
+ for (j = 0; j < argc; ++j) {
fputc(' ', stderr);
- sq_quote_print(stderr, argv[i]);
+ sq_quote_print(stderr, argv[j]);
}
putc('\n', stderr);
fflush(stderr);
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index 0ae18103c..e00a6ed6e 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -2291,7 +2291,7 @@ HTML
chomp $line;
$line_class_num = ($line_class_num + 1) % $line_class_len;
- if ($line =~ m/^([0-9a-fA-F]{40})\t\(\s*([^\t]+)\t(\d+) \+\d\d\d\d\t(\d+)\)(.*)$/) {
+ if ($line =~ m/^([0-9a-fA-F]{40})\t\(\s*([^\t]+)\t(\d+) [+-]\d\d\d\d\t(\d+)\)(.*)$/) {
$long_rev = $1;
$author = $2;
$time = $3;
diff --git a/http-fetch.c b/http-fetch.c
index 7f07d2a96..7619b338f 100644
--- a/http-fetch.c
+++ b/http-fetch.c
@@ -301,7 +301,7 @@ static void finish_object_request(struct object_request *obj_req)
unlink(obj_req->tmpfile);
return;
}
- if (memcmp(obj_req->sha1, obj_req->real_sha1, 20)) {
+ if (hashcmp(obj_req->sha1, obj_req->real_sha1)) {
unlink(obj_req->tmpfile);
return;
}
@@ -393,7 +393,7 @@ void prefetch(unsigned char *sha1)
char *filename = sha1_file_name(sha1);
newreq = xmalloc(sizeof(*newreq));
- memcpy(newreq->sha1, sha1, 20);
+ hashcpy(newreq->sha1, sha1);
newreq->repo = alt;
newreq->url = NULL;
newreq->local = -1;
@@ -1070,7 +1070,7 @@ static int fetch_object(struct alt_base *repo, unsigned char *sha1)
int ret = 0;
struct object_request *obj_req = object_queue_head;
- while (obj_req != NULL && memcmp(obj_req->sha1, sha1, 20))
+ while (obj_req != NULL && hashcmp(obj_req->sha1, sha1))
obj_req = obj_req->next;
if (obj_req == NULL)
return error("Couldn't find request for %s in the queue", hex);
@@ -1109,7 +1109,7 @@ static int fetch_object(struct alt_base *repo, unsigned char *sha1)
} else if (obj_req->zret != Z_STREAM_END) {
corrupt_object_found++;
ret = error("File %s (%s) corrupt", hex, obj_req->url);
- } else if (memcmp(obj_req->sha1, obj_req->real_sha1, 20)) {
+ } else if (hashcmp(obj_req->sha1, obj_req->real_sha1)) {
ret = error("File %s has bad hash", hex);
} else if (obj_req->rename < 0) {
ret = error("unable to write sha1 filename %s",
diff --git a/http-push.c b/http-push.c
index 2bd984576..04cb238e9 100644
--- a/http-push.c
+++ b/http-push.c
@@ -745,7 +745,7 @@ static void finish_request(struct transfer_request *request)
SHA1_Final(request->real_sha1, &request->c);
if (request->zret != Z_STREAM_END) {
unlink(request->tmpfile);
- } else if (memcmp(request->obj->sha1, request->real_sha1, 20)) {
+ } else if (hashcmp(request->obj->sha1, request->real_sha1)) {
unlink(request->tmpfile);
} else {
request->rename =
@@ -1700,7 +1700,7 @@ static int locking_available(void)
return lock_flags;
}
-struct object_list **add_one_object(struct object *obj, struct object_list **p)
+static struct object_list **add_one_object(struct object *obj, struct object_list **p)
{
struct object_list *entry = xmalloc(sizeof(struct object_list));
entry->item = obj;
@@ -1874,7 +1874,7 @@ static int one_local_ref(const char *refname, const unsigned char *sha1)
struct ref *ref;
int len = strlen(refname) + 1;
ref = xcalloc(1, sizeof(*ref) + len);
- memcpy(ref->new_sha1, sha1, 20);
+ hashcpy(ref->new_sha1, sha1);
memcpy(ref->name, refname, len);
*local_tail = ref;
local_tail = &ref->next;
@@ -1909,7 +1909,7 @@ static void one_remote_ref(char *refname)
}
ref = xcalloc(1, sizeof(*ref) + len);
- memcpy(ref->old_sha1, remote_sha1, 20);
+ hashcpy(ref->old_sha1, remote_sha1);
memcpy(ref->name, refname, len);
*remote_tail = ref;
remote_tail = &ref->next;
@@ -2164,7 +2164,7 @@ static void fetch_symref(const char *path, char **symref, unsigned char *sha1)
if (*symref != NULL)
free(*symref);
*symref = NULL;
- memset(sha1, 0, 20);
+ hashclr(sha1);
if (buffer.posn == 0)
return;
@@ -2416,7 +2416,7 @@ int main(int argc, char **argv)
if (!ref->peer_ref)
continue;
- if (!memcmp(ref->old_sha1, ref->peer_ref->new_sha1, 20)) {
+ if (!hashcmp(ref->old_sha1, ref->peer_ref->new_sha1)) {
if (push_verbosely || 1)
fprintf(stderr, "'%s': up-to-date\n", ref->name);
continue;
@@ -2445,7 +2445,7 @@ int main(int argc, char **argv)
continue;
}
}
- memcpy(ref->new_sha1, ref->peer_ref->new_sha1, 20);
+ hashcpy(ref->new_sha1, ref->peer_ref->new_sha1);
if (is_zero_sha1(ref->new_sha1)) {
error("cannot happen anymore");
rc = -3;
diff --git a/index-pack.c b/index-pack.c
index b20659c25..80bc6cb45 100644
--- a/index-pack.c
+++ b/index-pack.c
@@ -82,7 +82,7 @@ static void parse_pack_header(void)
SHA1_Init(&ctx);
SHA1_Update(&ctx, pack_base, pack_size - 20);
SHA1_Final(sha1, &ctx);
- if (memcmp(sha1, pack_base + pack_size - 20, 20))
+ if (hashcmp(sha1, pack_base + pack_size - 20))
die("packfile '%s' SHA1 mismatch", pack_name);
}
@@ -161,7 +161,7 @@ static void *unpack_raw_entry(unsigned long offset,
case OBJ_DELTA:
if (pos + 20 >= pack_limit)
bad_object(offset, "object extends past end of pack");
- memcpy(delta_base, pack_base + pos, 20);
+ hashcpy(delta_base, pack_base + pos);
pos += 20;
/* fallthru */
case OBJ_COMMIT:
@@ -189,7 +189,7 @@ static int find_delta(const unsigned char *base_sha1)
struct delta_entry *delta = &deltas[next];
int cmp;
- cmp = memcmp(base_sha1, delta->base_sha1, 20);
+ cmp = hashcmp(base_sha1, delta->base_sha1);
if (!cmp)
return next;
if (cmp < 0) {
@@ -210,9 +210,9 @@ static int find_deltas_based_on_sha1(const unsigned char *base_sha1,
if (first < 0)
return -1;
- while (first > 0 && !memcmp(deltas[first-1].base_sha1, base_sha1, 20))
+ while (first > 0 && !hashcmp(deltas[first - 1].base_sha1, base_sha1))
--first;
- while (last < end && !memcmp(deltas[last+1].base_sha1, base_sha1, 20))
+ while (last < end && !hashcmp(deltas[last + 1].base_sha1, base_sha1))
++last;
*first_index = first;
*last_index = last;
@@ -278,7 +278,7 @@ static int compare_delta_entry(const void *a, const void *b)
{
const struct delta_entry *delta_a = a;
const struct delta_entry *delta_b = b;
- return memcmp(delta_a->base_sha1, delta_b->base_sha1, 20);
+ return hashcmp(delta_a->base_sha1, delta_b->base_sha1);
}
static void parse_pack_objects(void)
@@ -304,7 +304,7 @@ static void parse_pack_objects(void)
if (obj->type == OBJ_DELTA) {
struct delta_entry *delta = &deltas[nr_deltas++];
delta->obj = obj;
- memcpy(delta->base_sha1, base_sha1, 20);
+ hashcpy(delta->base_sha1, base_sha1);
} else
sha1_object(data, data_size, obj->type, obj->sha1);
free(data);
@@ -350,7 +350,7 @@ static int sha1_compare(const void *_a, const void *_b)
{
struct object_entry *a = *(struct object_entry **)_a;
struct object_entry *b = *(struct object_entry **)_b;
- return memcmp(a->sha1, b->sha1, 20);
+ return hashcmp(a->sha1, b->sha1);
}
static void write_index_file(const char *index_name, unsigned char *sha1)
diff --git a/merge-tree.c b/merge-tree.c
index 7cf00be6d..c2e9a867e 100644
--- a/merge-tree.c
+++ b/merge-tree.c
@@ -152,7 +152,7 @@ static int same_entry(struct name_entry *a, struct name_entry *b)
{
return a->sha1 &&
b->sha1 &&
- !memcmp(a->sha1, b->sha1, 20) &&
+ !hashcmp(a->sha1, b->sha1) &&
a->mode == b->mode;
}
diff --git a/mktree.c b/mktree.c
index 93241385e..56205d1e0 100644
--- a/mktree.c
+++ b/mktree.c
@@ -30,7 +30,7 @@ static void append_to_tree(unsigned mode, unsigned char *sha1, char *path)
ent = entries[used++] = xmalloc(sizeof(**entries) + len + 1);
ent->mode = mode;
ent->len = len;
- memcpy(ent->sha1, sha1, 20);
+ hashcpy(ent->sha1, sha1);
memcpy(ent->name, path, len+1);
}
@@ -64,7 +64,7 @@ static void write_tree(unsigned char *sha1)
offset += sprintf(buffer + offset, "%o ", ent->mode);
offset += sprintf(buffer + offset, "%s", ent->name);
buffer[offset++] = 0;
- memcpy(buffer + offset, ent->sha1, 20);
+ hashcpy((unsigned char*)buffer + offset, ent->sha1);
offset += 20;
}
write_sha1_file(buffer, offset, tree_type, sha1);
diff --git a/object.c b/object.c
index b5d8ed467..60bf16b90 100644
--- a/object.c
+++ b/object.c
@@ -58,7 +58,7 @@ struct object *lookup_object(const unsigned char *sha1)
i = hashtable_index(sha1);
while ((obj = obj_hash[i]) != NULL) {
- if (!memcmp(sha1, obj->sha1, 20))
+ if (!hashcmp(sha1, obj->sha1))
break;
i++;
if (i == obj_hash_size)
@@ -91,7 +91,7 @@ void created_object(const unsigned char *sha1, struct object *obj)
obj->used = 0;
obj->type = OBJ_NONE;
obj->flags = 0;
- memcpy(obj->sha1, sha1, 20);
+ hashcpy(obj->sha1, sha1);
if (obj_hash_size - 1 <= nr_objs * 2)
grow_object_hash();
diff --git a/pack-check.c b/pack-check.c
index 3a62e1b7e..04c6c0082 100644
--- a/pack-check.c
+++ b/pack-check.c
@@ -29,10 +29,10 @@ static int verify_packfile(struct packed_git *p)
pack_base = p->pack_base;
SHA1_Update(&ctx, pack_base, pack_size - 20);
SHA1_Final(sha1, &ctx);
- if (memcmp(sha1, (char *) pack_base + pack_size - 20, 20))
+ if (hashcmp(sha1, (unsigned char *)pack_base + pack_size - 20))
return error("Packfile %s SHA1 mismatch with itself",
p->pack_name);
- if (memcmp(sha1, (char *) index_base + index_size - 40, 20))
+ if (hashcmp(sha1, (unsigned char *)index_base + index_size - 40))
return error("Packfile %s SHA1 mismatch with idx",
p->pack_name);
@@ -135,7 +135,7 @@ int verify_pack(struct packed_git *p, int verbose)
SHA1_Init(&ctx);
SHA1_Update(&ctx, index_base, index_size - 20);
SHA1_Final(sha1, &ctx);
- if (memcmp(sha1, (char *) index_base + index_size - 20, 20))
+ if (hashcmp(sha1, (unsigned char *)index_base + index_size - 20))
ret = error("Packfile index for %s SHA1 mismatch",
p->pack_name);
diff --git a/pack-redundant.c b/pack-redundant.c
index 92a09ed36..edb5524fc 100644
--- a/pack-redundant.c
+++ b/pack-redundant.c
@@ -139,7 +139,7 @@ static inline struct llist_item *llist_insert_sorted_unique(struct llist *list,
l = (hint == NULL) ? list->front : hint;
while (l) {
- int cmp = memcmp(l->sha1, sha1, 20);
+ int cmp = hashcmp(l->sha1, sha1);
if (cmp > 0) { /* we insert before this entry */
return llist_insert(list, prev, sha1);
}
@@ -162,7 +162,7 @@ redo_from_start:
l = (hint == NULL) ? list->front : hint;
prev = NULL;
while (l) {
- int cmp = memcmp(l->sha1, sha1, 20);
+ int cmp = hashcmp(l->sha1, sha1);
if (cmp > 0) /* not in list, since sorted */
return prev;
if(!cmp) { /* found */
@@ -256,7 +256,7 @@ static void cmp_two_packs(struct pack_list *p1, struct pack_list *p2)
while (p1_off <= p1->pack->index_size - 3 * 20 &&
p2_off <= p2->pack->index_size - 3 * 20)
{
- int cmp = memcmp(p1_base + p1_off, p2_base + p2_off, 20);
+ int cmp = hashcmp(p1_base + p1_off, p2_base + p2_off);
/* cmp ~ p1 - p2 */
if (cmp == 0) {
p1_hint = llist_sorted_remove(p1->unique_objects,
@@ -351,16 +351,16 @@ static size_t sizeof_union(struct packed_git *p1, struct packed_git *p2)
{
size_t ret = 0;
int p1_off, p2_off;
- char *p1_base, *p2_base;
+ unsigned char *p1_base, *p2_base;
p1_off = p2_off = 256 * 4 + 4;
- p1_base = (char *)p1->index_base;
- p2_base = (char *)p2->index_base;
+ p1_base = (unsigned char *)p1->index_base;
+ p2_base = (unsigned char *)p2->index_base;
while (p1_off <= p1->index_size - 3 * 20 &&
p2_off <= p2->index_size - 3 * 20)
{
- int cmp = memcmp(p1_base + p1_off, p2_base + p2_off, 20);
+ int cmp = hashcmp(p1_base + p1_off, p2_base + p2_off);
/* cmp ~ p1 - p2 */
if (cmp == 0) {
ret++;
diff --git a/patch-id.c b/patch-id.c
index 3b4c80f76..086d2d9c6 100644
--- a/patch-id.c
+++ b/patch-id.c
@@ -47,7 +47,7 @@ static void generate_id_list(void)
if (!get_sha1_hex(p, n)) {
flush_current_id(patchlen, sha1, &ctx);
- memcpy(sha1, n, 20);
+ hashcpy(sha1, n);
patchlen = 0;
continue;
}
diff --git a/read-cache.c b/read-cache.c
index 6bec833ee..b6982eac4 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -60,7 +60,7 @@ static int ce_compare_data(struct cache_entry *ce, struct stat *st)
if (fd >= 0) {
unsigned char sha1[20];
if (!index_fd(sha1, fd, st, 0, NULL))
- match = memcmp(sha1, ce->sha1, 20);
+ match = hashcmp(sha1, ce->sha1);
/* index_fd() closed the file descriptor already */
}
return match;
@@ -744,7 +744,7 @@ static int verify_hdr(struct cache_header *hdr, unsigned long size)
SHA1_Init(&c);
SHA1_Update(&c, hdr, size - 20);
SHA1_Final(sha1, &c);
- if (memcmp(sha1, (char *) hdr + size - 20, 20))
+ if (hashcmp(sha1, (unsigned char *)hdr + size - 20))
return error("bad index file sha1 signature");
return 0;
}
diff --git a/receive-pack.c b/receive-pack.c
index 81e91909b..201531626 100644
--- a/receive-pack.c
+++ b/receive-pack.c
@@ -247,8 +247,8 @@ static void read_head_info(void)
report_status = 1;
}
cmd = xmalloc(sizeof(struct command) + len - 80);
- memcpy(cmd->old_sha1, old_sha1, 20);
- memcpy(cmd->new_sha1, new_sha1, 20);
+ hashcpy(cmd->old_sha1, old_sha1);
+ hashcpy(cmd->new_sha1, new_sha1);
memcpy(cmd->ref_name, line + 82, len - 81);
cmd->error_string = "n/a (unpacker error)";
cmd->next = NULL;
diff --git a/refs.c b/refs.c
index 86ef91661..e70ef0ae0 100644
--- a/refs.c
+++ b/refs.c
@@ -29,7 +29,7 @@ const char *resolve_ref(const char *path, unsigned char *sha1, int reading)
if (lstat(path, &st) < 0) {
if (reading || errno != ENOENT)
return NULL;
- memset(sha1, 0, 20);
+ hashclr(sha1);
return path;
}
@@ -281,7 +281,7 @@ static struct ref_lock *verify_lock(struct ref_lock *lock,
unlock_ref(lock);
return NULL;
}
- if (memcmp(lock->old_sha1, old_sha1, 20)) {
+ if (hashcmp(lock->old_sha1, old_sha1)) {
error("Ref %s is at %s but expected %s", lock->ref_file,
sha1_to_hex(lock->old_sha1), sha1_to_hex(old_sha1));
unlock_ref(lock);
@@ -411,7 +411,7 @@ int write_ref_sha1(struct ref_lock *lock,
if (!lock)
return -1;
- if (!lock->force_write && !memcmp(lock->old_sha1, sha1, 20)) {
+ if (!lock->force_write && !hashcmp(lock->old_sha1, sha1)) {
unlock_ref(lock);
return 0;
}
@@ -475,7 +475,7 @@ int read_ref_at(const char *ref, unsigned long at_time, unsigned char *sha1)
die("Log %s is corrupt.", logfile);
if (get_sha1_hex(rec + 41, sha1))
die("Log %s is corrupt.", logfile);
- if (memcmp(logged_sha1, sha1, 20)) {
+ if (hashcmp(logged_sha1, sha1)) {
tz = strtoul(tz_c, NULL, 10);
fprintf(stderr,
"warning: Log %s has gap after %s.\n",
@@ -489,7 +489,7 @@ int read_ref_at(const char *ref, unsigned long at_time, unsigned char *sha1)
else {
if (get_sha1_hex(rec + 41, logged_sha1))
die("Log %s is corrupt.", logfile);
- if (memcmp(logged_sha1, sha1, 20)) {
+ if (hashcmp(logged_sha1, sha1)) {
tz = strtoul(tz_c, NULL, 10);
fprintf(stderr,
"warning: Log %s unexpectedly ended on %s.\n",
diff --git a/revision.c b/revision.c
index 5a91d06b9..1d89d7273 100644
--- a/revision.c
+++ b/revision.c
@@ -496,7 +496,7 @@ static int add_parents_only(struct rev_info *revs, const char *arg, int flags)
it = get_reference(revs, arg, sha1, 0);
if (it->type != OBJ_TAG)
break;
- memcpy(sha1, ((struct tag*)it)->tagged->sha1, 20);
+ hashcpy(sha1, ((struct tag*)it)->tagged->sha1);
}
if (it->type != OBJ_COMMIT)
return 0;
diff --git a/send-pack.c b/send-pack.c
index 43e10b0a6..fd79a6192 100644
--- a/send-pack.c
+++ b/send-pack.c
@@ -185,7 +185,7 @@ static int one_local_ref(const char *refname, const unsigned char *sha1)
struct ref *ref;
int len = strlen(refname) + 1;
ref = xcalloc(1, sizeof(*ref) + len);
- memcpy(ref->new_sha1, sha1, 20);
+ hashcpy(ref->new_sha1, sha1);
memcpy(ref->name, refname, len);
*local_tail = ref;
local_tail = &ref->next;
@@ -265,7 +265,7 @@ static int send_pack(int in, int out, int nr_refspec, char **refspec)
char old_hex[60], *new_hex;
if (!ref->peer_ref)
continue;
- if (!memcmp(ref->old_sha1, ref->peer_ref->new_sha1, 20)) {
+ if (!hashcmp(ref->old_sha1, ref->peer_ref->new_sha1)) {
if (verbose)
fprintf(stderr, "'%s': up-to-date\n", ref->name);
continue;
@@ -310,7 +310,7 @@ static int send_pack(int in, int out, int nr_refspec, char **refspec)
continue;
}
}
- memcpy(ref->new_sha1, ref->peer_ref->new_sha1, 20);
+ hashcpy(ref->new_sha1, ref->peer_ref->new_sha1);
if (is_zero_sha1(ref->new_sha1)) {
error("cannot happen anymore");
ret = -3;
diff --git a/sha1_file.c b/sha1_file.c
index 18dece46b..769a80984 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -463,6 +463,7 @@ int use_packed_git(struct packed_git *p)
int fd;
struct stat st;
void *map;
+ struct pack_header *hdr;
pack_mapped += p->pack_size;
while (PACK_MAX_SZ < pack_mapped && unuse_one_packed_git())
@@ -482,13 +483,24 @@ int use_packed_git(struct packed_git *p)
die("packfile %s cannot be mapped.", p->pack_name);
p->pack_base = map;
+ /* Check if we understand this pack file. If we don't we're
+ * likely too old to handle it.
+ */
+ hdr = map;
+ if (hdr->hdr_signature != htonl(PACK_SIGNATURE))
+ die("packfile %s isn't actually a pack.", p->pack_name);
+ if (!pack_version_ok(hdr->hdr_version))
+ die("packfile %s is version %i and not supported"
+ " (try upgrading GIT to a newer version)",
+ p->pack_name, ntohl(hdr->hdr_version));
+
/* Check if the pack file matches with the index file.
* this is cheap.
*/
- if (memcmp((char*)(p->index_base) + p->index_size - 40,
- (char *) p->pack_base + p->pack_size - 20,
- 20)) {
-
+ if (hashcmp((unsigned char *)(p->index_base) +
+ p->index_size - 40,
+ (unsigned char *)p->pack_base +
+ p->pack_size - 20)) {
die("packfile %s does not match index.", p->pack_name);
}
}
@@ -528,7 +540,7 @@ struct packed_git *add_packed_git(char *path, int path_len, int local)
p->pack_use_cnt = 0;
p->pack_local = local;
if ((path_len > 44) && !get_sha1_hex(path + path_len - 44, sha1))
- memcpy(p->sha1, sha1, 20);
+ hashcpy(p->sha1, sha1);
return p;
}
@@ -559,7 +571,7 @@ struct packed_git *parse_pack_index_file(const unsigned char *sha1, char *idx_pa
p->pack_base = NULL;
p->pack_last_used = 0;
p->pack_use_cnt = 0;
- memcpy(p->sha1, sha1, 20);
+ hashcpy(p->sha1, sha1);
return p;
}
@@ -643,7 +655,7 @@ int check_sha1_signature(const unsigned char *sha1, void *map, unsigned long siz
SHA1_Update(&c, header, 1+sprintf(header, "%s %lu", type, size));
SHA1_Update(&c, map, size);
SHA1_Final(real_sha1, &c);
- return memcmp(sha1, real_sha1, 20) ? -1 : 0;
+ return hashcmp(sha1, real_sha1) ? -1 : 0;
}
void *map_sha1_file(const unsigned char *sha1, unsigned long *size)
@@ -941,7 +953,7 @@ int check_reuse_pack_delta(struct packed_git *p, unsigned long offset,
ptr = unpack_object_header(p, ptr, kindp, sizep);
if (*kindp != OBJ_DELTA)
goto done;
- memcpy(base, (char *) p->pack_base + ptr, 20);
+ hashcpy(base, (unsigned char *) p->pack_base + ptr);
status = 0;
done:
unuse_packed_git(p);
@@ -969,7 +981,7 @@ void packed_object_info_detail(struct pack_entry *e,
if (p->pack_size <= offset + 20)
die("pack file %s records an incomplete delta base",
p->pack_name);
- memcpy(base_sha1, pack, 20);
+ hashcpy(base_sha1, pack);
do {
struct pack_entry base_ent;
unsigned long junk;
@@ -1045,9 +1057,6 @@ static int packed_object_info(struct pack_entry *entry,
return 0;
}
-/* forward declaration for a mutually recursive function */
-static void *unpack_entry(struct pack_entry *, char *, unsigned long *);
-
static void *unpack_delta_entry(unsigned char *base_sha1,
unsigned long delta_size,
unsigned long left,
@@ -1192,7 +1201,7 @@ int nth_packed_object_sha1(const struct packed_git *p, int n,
void *index = p->index_base + 256;
if (n < 0 || num_packed_objects(p) <= n)
return -1;
- memcpy(sha1, (char *) index + (24 * n) + 4, 20);
+ hashcpy(sha1, (unsigned char *) index + (24 * n) + 4);
return 0;
}
@@ -1206,10 +1215,10 @@ int find_pack_entry_one(const unsigned char *sha1,
do {
int mi = (lo + hi) / 2;
- int cmp = memcmp((char *) index + (24 * mi) + 4, sha1, 20);
+ int cmp = hashcmp((unsigned char *)index + (24 * mi) + 4, sha1);
if (!cmp) {
e->offset = ntohl(*((unsigned int *) ((char *) index + (24 * mi))));
- memcpy(e->sha1, sha1, 20);
+ hashcpy(e->sha1, sha1);
e->p = p;
return 1;
}
@@ -1322,7 +1331,7 @@ void *read_object_with_reference(const unsigned char *sha1,
unsigned long isize;
unsigned char actual_sha1[20];
- memcpy(actual_sha1, sha1, 20);
+ hashcpy(actual_sha1, sha1);
while (1) {
int ref_length = -1;
const char *ref_type = NULL;
@@ -1333,7 +1342,7 @@ void *read_object_with_reference(const unsigned char *sha1,
if (!strcmp(type, required_type)) {
*size = isize;
if (actual_sha1_return)
- memcpy(actual_sha1_return, actual_sha1, 20);
+ hashcpy(actual_sha1_return, actual_sha1);
return buffer;
}
/* Handle references */
@@ -1528,7 +1537,7 @@ int write_sha1_file(void *buf, unsigned long len, const char *type, unsigned cha
*/
filename = write_sha1_file_prepare(buf, len, type, sha1, hdr, &hdrlen);
if (returnsha1)
- memcpy(returnsha1, sha1, 20);
+ hashcpy(returnsha1, sha1);
if (has_sha1_file(sha1))
return 0;
fd = open(filename, O_RDONLY);
@@ -1715,7 +1724,7 @@ int write_sha1_from_fd(const unsigned char *sha1, int fd, char *buffer,
unlink(tmpfile);
return error("File %s corrupted", sha1_to_hex(sha1));
}
- if (memcmp(sha1, real_sha1, 20)) {
+ if (hashcmp(sha1, real_sha1)) {
unlink(tmpfile);
return error("File %s has bad hash", sha1_to_hex(sha1));
}
diff --git a/sha1_name.c b/sha1_name.c
index f567454d2..3f6b77ccf 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -84,7 +84,7 @@ static int find_short_packed_object(int len, const unsigned char *match, unsigne
int cmp;
nth_packed_object_sha1(p, mid, now);
- cmp = memcmp(match, now, 20);
+ cmp = hashcmp(match, now);
if (!cmp) {
first = mid;
break;
@@ -103,10 +103,10 @@ static int find_short_packed_object(int len, const unsigned char *match, unsigne
!match_sha(len, match, next)) {
/* unique within this pack */
if (!found) {
- memcpy(found_sha1, now, 20);
+ hashcpy(found_sha1, now);
found++;
}
- else if (memcmp(found_sha1, now, 20)) {
+ else if (hashcmp(found_sha1, now)) {
found = 2;
break;
}
@@ -120,7 +120,7 @@ static int find_short_packed_object(int len, const unsigned char *match, unsigne
}
}
if (found == 1)
- memcpy(sha1, found_sha1, 20);
+ hashcpy(sha1, found_sha1);
return found;
}
@@ -140,13 +140,13 @@ static int find_unique_short_object(int len, char *canonical,
if (1 < has_unpacked || 1 < has_packed)
return SHORT_NAME_AMBIGUOUS;
if (has_unpacked != has_packed) {
- memcpy(sha1, (has_packed ? packed_sha1 : unpacked_sha1), 20);
+ hashcpy(sha1, (has_packed ? packed_sha1 : unpacked_sha1));
return 0;
}
/* Both have unique ones -- do they match? */
- if (memcmp(packed_sha1, unpacked_sha1, 20))
+ if (hashcmp(packed_sha1, unpacked_sha1))
return SHORT_NAME_AMBIGUOUS;
- memcpy(sha1, packed_sha1, 20);
+ hashcpy(sha1, packed_sha1);
return 0;
}
@@ -159,7 +159,7 @@ static int get_short_sha1(const char *name, int len, unsigned char *sha1,
if (len < MINIMUM_ABBREV)
return -1;
- memset(res, 0, 20);
+ hashclr(res);
memset(canonical, 'x', 40);
for (i = 0; i < len ;i++) {
unsigned char c = name[i];
@@ -320,13 +320,13 @@ static int get_parent(const char *name, int len,
if (parse_commit(commit))
return -1;
if (!idx) {
- memcpy(result, commit->object.sha1, 20);
+ hashcpy(result, commit->object.sha1);
return 0;
}
p = commit->parents;
while (p) {
if (!--idx) {
- memcpy(result, p->item->object.sha1, 20);
+ hashcpy(result, p->item->object.sha1);
return 0;
}
p = p->next;
@@ -347,9 +347,9 @@ static int get_nth_ancestor(const char *name, int len,
if (!commit || parse_commit(commit) || !commit->parents)
return -1;
- memcpy(sha1, commit->parents->item->object.sha1, 20);
+ hashcpy(sha1, commit->parents->item->object.sha1);
}
- memcpy(result, sha1, 20);
+ hashcpy(result, sha1);
return 0;
}
@@ -401,7 +401,7 @@ static int peel_onion(const char *name, int len, unsigned char *sha1)
o = deref_tag(o, name, sp - name - 2);
if (!o || (!o->parsed && !parse_object(o->sha1)))
return -1;
- memcpy(sha1, o->sha1, 20);
+ hashcpy(sha1, o->sha1);
}
else {
/* At this point, the syntax look correct, so
@@ -413,7 +413,7 @@ static int peel_onion(const char *name, int len, unsigned char *sha1)
if (!o || (!o->parsed && !parse_object(o->sha1)))
return -1;
if (o->type == expected_type) {
- memcpy(sha1, o->sha1, 20);
+ hashcpy(sha1, o->sha1);
return 0;
}
if (o->type == OBJ_TAG)
@@ -520,7 +520,7 @@ int get_sha1(const char *name, unsigned char *sha1)
memcmp(ce->name, cp, namelen))
break;
if (ce_stage(ce) == stage) {
- memcpy(sha1, ce->sha1, 20);
+ hashcpy(sha1, ce->sha1);
return 0;
}
pos++;
diff --git a/ssh-fetch.c b/ssh-fetch.c
index 0b89df6dd..b006c5c98 100644
--- a/ssh-fetch.c
+++ b/ssh-fetch.c
@@ -67,7 +67,7 @@ int fetch(unsigned char *sha1)
signed char remote;
struct object_list *temp;
- if (memcmp(sha1, in_transit->item->sha1, 20)) {
+ if (hashcmp(sha1, in_transit->item->sha1)) {
/* we must have already fetched it to clean the queue */
return has_sha1_file(sha1) ? 0 : -1;
}
diff --git a/t/t7001-mv.sh b/t/t7001-mv.sh
index e5e0bb9d5..b7fcdb390 100755
--- a/t/t7001-mv.sh
+++ b/t/t7001-mv.sh
@@ -82,4 +82,8 @@ test_expect_failure \
'do not move directory over existing directory' \
'mkdir path0 && mkdir path0/path2 && git-mv path2 path0'
+test_expect_success \
+ 'move into "."' \
+ 'git-mv path1/path2/ .'
+
test_done
diff --git a/tree-diff.c b/tree-diff.c
index 916f489c5..7e2f4f088 100644
--- a/tree-diff.c
+++ b/tree-diff.c
@@ -39,8 +39,7 @@ static int compare_tree_entry(struct tree_desc *t1, struct tree_desc *t2, const
show_entry(opt, "+", t2, base);
return 1;
}
- if (!opt->find_copies_harder &&
- !memcmp(sha1, sha2, 20) && mode1 == mode2)
+ if (!opt->find_copies_harder && !hashcmp(sha1, sha2) && mode1 == mode2)
return 0;
/*
diff --git a/tree-walk.c b/tree-walk.c
index 3f83e98f3..14cc5aea6 100644
--- a/tree-walk.c
+++ b/tree-walk.c
@@ -179,7 +179,7 @@ static int find_tree_entry(struct tree_desc *t, const char *name, unsigned char
if (cmp < 0)
break;
if (entrylen == namelen) {
- memcpy(result, sha1, 20);
+ hashcpy(result, sha1);
return 0;
}
if (name[entrylen] != '/')
@@ -187,7 +187,7 @@ static int find_tree_entry(struct tree_desc *t, const char *name, unsigned char
if (!S_ISDIR(*mode))
break;
if (++entrylen == namelen) {
- memcpy(result, sha1, 20);
+ hashcpy(result, sha1);
return 0;
}
return get_tree_entry(sha1, name + entrylen, result, mode);
diff --git a/tree.c b/tree.c
index ef456be9d..ea386e506 100644
--- a/tree.c
+++ b/tree.c
@@ -25,7 +25,7 @@ static int read_one_entry(const unsigned char *sha1, const char *base, int basel
ce->ce_flags = create_ce_flags(baselen + len, stage);
memcpy(ce->name, base, baselen);
memcpy(ce->name + baselen, pathname, len+1);
- memcpy(ce->sha1, sha1, 20);
+ hashcpy(ce->sha1, sha1);
return add_cache_entry(ce, ADD_CACHE_OK_TO_ADD|ADD_CACHE_SKIP_DFCHECK);
}
diff --git a/unpack-trees.c b/unpack-trees.c
index 43ed12484..3ac0289b3 100644
--- a/unpack-trees.c
+++ b/unpack-trees.c
@@ -200,7 +200,7 @@ static int unpack_trees_rec(struct tree_entry_list **posns, int len,
any_files = 1;
- memcpy(ce->sha1, posns[i]->sha1, 20);
+ hashcpy(ce->sha1, posns[i]->sha1);
src[i + o->merge] = ce;
subposns[i] = df_conflict_list;
posns[i] = posns[i]->next;
@@ -417,7 +417,7 @@ static int same(struct cache_entry *a, struct cache_entry *b)
if (!a && !b)
return 1;
return a->ce_mode == b->ce_mode &&
- !memcmp(a->sha1, b->sha1, 20);
+ !hashcmp(a->sha1, b->sha1);
}
diff --git a/upload-pack.c b/upload-pack.c
index fcf279843..51ce936b0 100644
--- a/upload-pack.c
+++ b/upload-pack.c
@@ -374,7 +374,7 @@ static int get_common_commits(void)
sha1_to_hex(sha1),
multi_ack ? " continue" : "");
if (multi_ack)
- memcpy(last_sha1, sha1, 20);
+ hashcpy(last_sha1, sha1);
}
continue;
}
diff --git a/write_or_die.c b/write_or_die.c
new file mode 100644
index 000000000..ab4cb8a69
--- /dev/null
+++ b/write_or_die.c
@@ -0,0 +1,20 @@
+#include "cache.h"
+
+void write_or_die(int fd, const void *buf, size_t count)
+{
+ const char *p = buf;
+ ssize_t written;
+
+ while (count > 0) {
+ written = xwrite(fd, p, count);
+ if (written == 0)
+ die("disk full?");
+ else if (written < 0) {
+ if (errno == EPIPE)
+ exit(0);
+ die("write error (%s)", strerror(errno));
+ }
+ count -= written;
+ p += written;
+ }
+}