Merge branch 'master' into js/diff-ni
* master: (201 commits) Documentation: link in 1.5.0.2 material to the top documentation page. Documentation: document remote.<name>.tagopt GIT 1.5.0.2 git-remote: support remotes with a dot in the name Documentation: describe "-f/-t/-m" options to "git-remote add" diff --cc: fix display of symlink conflicts during a merge. merge-recursive: fix longstanding bug in merging symlinks merge-index: fix longstanding bug in merging symlinks diff --cached: give more sensible error message when HEAD is yet to be created. Update tests to use test-chmtime Add test-chmtime: a utility to change mtime on files Add Release Notes to prepare for 1.5.0.2 Allow arbitrary number of arguments to git-pack-objects rerere: do not deal with symlinks. rerere: do not skip two conflicted paths next to each other. Don't modify CREDITS-FILE if it hasn't changed. diff-patch: Avoid emitting double-slashes in textual patch. Reword git-am 3-way fallback failure message. Limit filename for format-patch core.legacyheaders: Use the description used in RelNotes-1.5.0 ...
This commit is contained in:
commit
048f48a2fd
1
.gitignore
vendored
1
.gitignore
vendored
@ -139,6 +139,7 @@ git-whatchanged
|
||||
git-write-tree
|
||||
git-core-*/?*
|
||||
gitweb/gitweb.cgi
|
||||
test-chmtime
|
||||
test-date
|
||||
test-delta
|
||||
test-dump-cache-tree
|
||||
|
1
.mailmap
1
.mailmap
@ -27,6 +27,7 @@ Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
|
||||
Ramsay Allan Jones <ramsay@ramsay1.demon.co.uk>
|
||||
René Scharfe <rene.scharfe@lsrfire.ath.cx>
|
||||
Robert Fitzsimons <robfitz@273k.net>
|
||||
Sam Vilain <sam@vilain.net>
|
||||
Santi Béjar <sbejar@gmail.com>
|
||||
Sean Estabrooks <seanlkml@sympatico.ca>
|
||||
Shawn O. Pearce <spearce@spearce.org>
|
||||
|
65
Documentation/RelNotes-1.5.0.2.txt
Normal file
65
Documentation/RelNotes-1.5.0.2.txt
Normal file
@ -0,0 +1,65 @@
|
||||
GIT v1.5.0.2 Release Notes
|
||||
==========================
|
||||
|
||||
Fixes since v1.5.0.1
|
||||
--------------------
|
||||
|
||||
* Bugfixes
|
||||
|
||||
- Automated merge conflict handling when changes to symbolic
|
||||
links conflicted were completely broken. The merge-resolve
|
||||
strategy created a regular file with conflict markers in it
|
||||
in place of the symbolic link. The default strategy,
|
||||
merge-recursive was even more broken. It removed the path
|
||||
that was pointed at by the symbolic link. Both of these
|
||||
problems have been fixed.
|
||||
|
||||
- 'git diff maint master next' did not correctly give combined
|
||||
diff across three trees.
|
||||
|
||||
- 'git fast-import' portability fix for Solaris.
|
||||
|
||||
- 'git show-ref --verify' without arguments did not error out
|
||||
but segfaulted.
|
||||
|
||||
- 'git diff :tracked-file `pwd`/an-untracked-file' gave an extra
|
||||
slashes after a/ and b/.
|
||||
|
||||
- 'git format-patch' produced too long filenames if the commit
|
||||
message had too long line at the beginning.
|
||||
|
||||
- Running 'make all' and then without changing anything
|
||||
running 'make install' still rebuilt some files. This
|
||||
was inconvenient when building as yourself and then
|
||||
installing as root (especially problematic when the source
|
||||
directory is on NFS and root is mapped to nobody).
|
||||
|
||||
- 'git-rerere' failed to deal with two unconflicted paths that
|
||||
sorted next to each other.
|
||||
|
||||
- 'git-rerere' attempted to open(2) a symlink and failed if
|
||||
there was a conflict. Since a conflicting change to a
|
||||
symlink would not benefit from rerere anyway, the command
|
||||
now ignores conflicting changes to symlinks.
|
||||
|
||||
- 'git-repack' did not like to pass more than 64 arguments
|
||||
internally to underlying 'rev-list' logic, which made it
|
||||
impossible to repack after accumulating many (small) packs
|
||||
in the repository.
|
||||
|
||||
- 'git-diff' to review the combined diff during a conflicted
|
||||
merge were not reading the working tree version correctly
|
||||
when changes to a symbolic link conflicted. It should have
|
||||
read the data using readlink(2) but read from the regular
|
||||
file the symbolic link pointed at.
|
||||
|
||||
- 'git-remote' did not like period in a remote's name.
|
||||
|
||||
* Documentation updates
|
||||
|
||||
- added and clarified core.bare, core.legacyheaders configurations.
|
||||
|
||||
- updated "git-clone --depth" documentation.
|
||||
|
||||
|
||||
* Assorted git-gui fixes.
|
@ -448,7 +448,7 @@ Updates in v1.5.0 since v1.4.4 series
|
||||
- There is a partial support for 'shallow' repositories that
|
||||
keeps only recent history. A 'shallow clone' is created by
|
||||
specifying how deep that truncated history should be
|
||||
(e.g. "git clone --depth=5 git://some.where/repo.git").
|
||||
(e.g. "git clone --depth 5 git://some.where/repo.git").
|
||||
|
||||
Currently a shallow repository has number of limitations:
|
||||
|
||||
|
@ -5,7 +5,8 @@ The git configuration file contains a number of variables that affect
|
||||
the git command's behavior. `.git/config` file for each repository
|
||||
is used to store the information for that repository, and
|
||||
`$HOME/.gitconfig` is used to store per user information to give
|
||||
fallback values for `.git/config` file.
|
||||
fallback values for `.git/config` file. The file `/etc/gitconfig`
|
||||
can be used to store system-wide defaults.
|
||||
|
||||
They can be used by both the git plumbing
|
||||
and the porcelains. The variables are divided into sections, where
|
||||
@ -142,6 +143,18 @@ core.preferSymlinkRefs::
|
||||
This is sometimes needed to work with old scripts that
|
||||
expect HEAD to be a symbolic link.
|
||||
|
||||
core.bare::
|
||||
If true this repository is assumed to be 'bare' and has no
|
||||
working directory associated with it. If this is the case a
|
||||
number of commands that require a working directory will be
|
||||
disabled, such as gitlink:git-add[1] or gitlink:git-merge[1].
|
||||
+
|
||||
This setting is automatically guessed by gitlink:git-clone[1] or
|
||||
gitlink:git-init[1] when the repository was created. By default a
|
||||
repository that ends in "/.git" is assumed to be not bare (bare =
|
||||
false), while all other repositories are assumed to be bare (bare
|
||||
= true).
|
||||
|
||||
core.logAllRefUpdates::
|
||||
Updates to a ref <ref> is logged to the file
|
||||
"$GIT_DIR/logs/<ref>", by appending the new and old
|
||||
@ -180,10 +193,17 @@ core.compression::
|
||||
slowest.
|
||||
|
||||
core.legacyheaders::
|
||||
A boolean which enables the legacy object header format in case
|
||||
you want to interoperate with old clients accessing the object
|
||||
database directly (where the "http://" and "rsync://" protocols
|
||||
count as direct access).
|
||||
A boolean which
|
||||
changes the format of loose objects so that they are more
|
||||
efficient to pack and to send out of the repository over git
|
||||
native protocol, since v1.4.2. However, loose objects
|
||||
written in the new format cannot be read by git older than
|
||||
that version; people fetching from your repository using
|
||||
older versions of git over dumb transports (e.g. http)
|
||||
will also be affected.
|
||||
+
|
||||
To let git use the new loose object format, you have to
|
||||
set core.legacyheaders to false.
|
||||
|
||||
core.packedGitWindowSize::
|
||||
Number of bytes of a pack file to map into memory in a
|
||||
@ -451,6 +471,10 @@ remote.<name>.push::
|
||||
The default set of "refspec" for gitlink:git-push[1]. See
|
||||
gitlink:git-push[1].
|
||||
|
||||
remote.<name>.skipDefaultUpdate::
|
||||
If true, this remote will be skipped by default when updating
|
||||
using the remote subcommand of gitlink:git-remote[1].
|
||||
|
||||
remote.<name>.receivepack::
|
||||
The default program to execute on the remote side when pushing. See
|
||||
option \--exec of gitlink:git-push[1].
|
||||
@ -459,6 +483,14 @@ remote.<name>.uploadpack::
|
||||
The default program to execute on the remote side when fetching. See
|
||||
option \--exec of gitlink:git-fetch-pack[1].
|
||||
|
||||
remote.<name>.tagopt::
|
||||
Setting this value to --no-tags disables automatic tag following when fetching
|
||||
from remote <name>
|
||||
|
||||
remotes.<group>::
|
||||
The list of remotes which are fetched by "git remote update
|
||||
<group>". See gitlink:git-remote[1].
|
||||
|
||||
repack.usedeltabaseoffset::
|
||||
Allow gitlink:git-repack[1] to create packs that uses
|
||||
delta-base offset. Defaults to false.
|
||||
|
@ -11,7 +11,7 @@ SYNOPSIS
|
||||
[verse]
|
||||
'git-clone' [--template=<template_directory>] [-l [-s]] [-q] [-n] [--bare]
|
||||
[-o <name>] [-u <upload-pack>] [--reference <repository>]
|
||||
[--depth=<depth>] <repository> [<directory>]
|
||||
[--depth <depth>] <repository> [<directory>]
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
@ -96,7 +96,7 @@ OPTIONS
|
||||
if unset the templates are taken from the installation
|
||||
defined default, typically `/usr/share/git-core/templates`.
|
||||
|
||||
--depth=<depth>::
|
||||
--depth <depth>::
|
||||
Create a 'shallow' clone with a history truncated to the
|
||||
specified number of revs. A shallow repository has
|
||||
number of limitations (you cannot clone or fetch from
|
||||
|
@ -8,7 +8,7 @@ git-cvsexportcommit - Export a single commit to a CVS checkout
|
||||
|
||||
SYNOPSIS
|
||||
--------
|
||||
'git-cvsexportcommit' [-h] [-v] [-c] [-P] [-p] [-a] [-f] [-m msgprefix] [PARENTCOMMIT] COMMITID
|
||||
'git-cvsexportcommit' [-h] [-v] [-c] [-P] [-p] [-a] [-d cvsroot] [-f] [-m msgprefix] [PARENTCOMMIT] COMMITID
|
||||
|
||||
|
||||
DESCRIPTION
|
||||
@ -43,6 +43,11 @@ OPTIONS
|
||||
Add authorship information. Adds Author line, and Committer (if
|
||||
different from Author) to the message.
|
||||
|
||||
-d::
|
||||
Set an alternative CVSROOT to use. This corresponds to the CVS
|
||||
-d parameter. Usually users will not want to set this, except
|
||||
if using CVS in an asymmetric fashion.
|
||||
|
||||
-f::
|
||||
Force the merge even if the files are not up to date.
|
||||
|
||||
|
@ -13,6 +13,7 @@ SYNOPSIS
|
||||
'git-remote' add <name> <url>
|
||||
'git-remote' show <name>
|
||||
'git-remote' prune <name>
|
||||
'git-remote' update [group]
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
@ -31,6 +32,19 @@ subcommands are available to perform operations on the remotes.
|
||||
Adds a remote named <name> for the repository at
|
||||
<url>. The command `git fetch <name>` can then be used to create and
|
||||
update remote-tracking branches <name>/<branch>.
|
||||
+
|
||||
With `-f` option, `git fetch <name>` is run immediately after
|
||||
the remote information is set up.
|
||||
+
|
||||
With `-t <branch>` option, instead of the default glob
|
||||
refspec for the remote to track all branches under
|
||||
`$GIT_DIR/remotes/<name>/`, a refspec to track only `<branch>`
|
||||
is created. You can give more than one `-t <branch>` to track
|
||||
multiple branche without grabbing all branches.
|
||||
+
|
||||
With `-m <master>` option, `$GIT_DIR/remotes/<name>/HEAD` is set
|
||||
up to point at remote's `<master>` branch instead of whatever
|
||||
branch the `HEAD` at the remote repository actually points at.
|
||||
|
||||
'show'::
|
||||
|
||||
@ -40,7 +54,17 @@ Gives some information about the remote <name>.
|
||||
|
||||
Deletes all stale tracking branches under <name>.
|
||||
These stale branches have already been removed from the remote repository
|
||||
referenced by <name>, but are still locally available in "remotes/<name>".
|
||||
referenced by <name>, but are still locally available in
|
||||
"remotes/<name>".
|
||||
|
||||
'update'::
|
||||
|
||||
Fetch updates for a named set of remotes in the repository as defined by
|
||||
remotes.<group>. If a named group is not specified on the command line,
|
||||
the configuration parameter remotes.default will get used; if
|
||||
remotes.default is not defined, all remotes which do not the
|
||||
configuration parameter remote.<name>.skipDefaultUpdate set to true will
|
||||
be updated. (See gitlink:git-config[1]).
|
||||
|
||||
|
||||
DISCUSSION
|
||||
|
@ -13,14 +13,13 @@ DESCRIPTION
|
||||
-----------
|
||||
git-svn is a simple conduit for changesets between Subversion and git.
|
||||
It is not to be confused with gitlink:git-svnimport[1], which is
|
||||
read-only and geared towards tracking multiple branches.
|
||||
read-only.
|
||||
|
||||
git-svn was originally designed for an individual developer who wants a
|
||||
bidirectional flow of changesets between a single branch in Subversion
|
||||
and an arbitrary number of branches in git. Since its inception,
|
||||
git-svn has gained the ability to track multiple branches in a manner
|
||||
similar to git-svnimport; but it cannot (yet) automatically detect new
|
||||
branches and tags like git-svnimport does.
|
||||
similar to git-svnimport.
|
||||
|
||||
git-svn is especially useful when it comes to tracking repositories
|
||||
not organized in the way Subversion developers recommend (trunk,
|
||||
@ -31,26 +30,80 @@ COMMANDS
|
||||
--
|
||||
|
||||
'init'::
|
||||
Creates an empty git repository with additional metadata
|
||||
directories for git-svn. The Subversion URL must be specified
|
||||
as a command-line argument. Optionally, the target directory
|
||||
to operate on can be specified as a second argument. Normally
|
||||
this command initializes the current directory.
|
||||
Initializes an empty git repository with additional
|
||||
metadata directories for git-svn. The Subversion URL
|
||||
may be specified as a command-line argument, or as full
|
||||
URL arguments to -T/-t/-b. Optionally, the target
|
||||
directory to operate on can be specified as a second
|
||||
argument. Normally this command initializes the current
|
||||
directory.
|
||||
|
||||
-T<trunk_subdir>::
|
||||
--trunk=<trunk_subdir>::
|
||||
-t<tags_subdir>::
|
||||
--tags=<tags_subdir>::
|
||||
-b<branches_subdir>::
|
||||
--branches=<branches_subdir>::
|
||||
These are optional command-line options for init. Each of
|
||||
these flags can point to a relative repository path
|
||||
(--tags=project/tags') or a full url
|
||||
(--tags=https://foo.org/project/tags)
|
||||
|
||||
--no-metadata::
|
||||
Set the 'noMetadata' option in the [svn-remote] config.
|
||||
--use-svm-props::
|
||||
Set the 'useSvmProps' option in the [svn-remote] config.
|
||||
--use-svnsync-props::
|
||||
Set the 'useSvnsyncProps' option in the [svn-remote] config.
|
||||
--rewrite-root=<URL>::
|
||||
Set the 'rewriteRoot' option in the [svn-remote] config.
|
||||
--username=<USER>::
|
||||
For transports that SVN handles authentication for (http,
|
||||
https, and plain svn), specify the username. For other
|
||||
transports (eg svn+ssh://), you must include the username in
|
||||
the URL, eg svn+ssh://foo@svn.bar.com/project
|
||||
|
||||
--prefix=<prefix>
|
||||
This allows one to specify a prefix which is prepended
|
||||
to the names of remotes if trunk/branches/tags are
|
||||
specified. The prefix does not automatically include a
|
||||
trailing slash, so be sure you include one in the
|
||||
argument if that is what you want. This is useful if
|
||||
you wish to track multiple projects that share a common
|
||||
repository.
|
||||
|
||||
'fetch'::
|
||||
|
||||
Fetch unfetched revisions from the Subversion URL we are
|
||||
tracking. refs/remotes/git-svn will be updated to the
|
||||
latest revision.
|
||||
Fetch unfetched revisions from the Subversion remote we are
|
||||
tracking. The name of the [svn-remote "..."] section in the
|
||||
.git/config file may be specified as an optional command-line
|
||||
argument.
|
||||
|
||||
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 'dcommit'
|
||||
command (see below) to write git commits back to
|
||||
remotes/git-svn.
|
||||
'clone'::
|
||||
Runs 'init' and 'fetch'. It will automatically create a
|
||||
directory based on the basename of the URL passed to it;
|
||||
or if a second argument is passed; it will create a directory
|
||||
and work within that. It accepts all arguments that the
|
||||
'init' and 'fetch' commands accept; with the exception of
|
||||
'--fetch-all'. After a repository is cloned, the 'fetch'
|
||||
command will be able to update revisions without affecting
|
||||
the working tree; and the 'rebase' command will be able
|
||||
to update the working tree with the latest changes.
|
||||
|
||||
See '<<fetch-args,Additional Fetch Arguments>>' if you are interested in
|
||||
manually joining branches on commit.
|
||||
'rebase'::
|
||||
This fetches revisions from the SVN parent of the current HEAD
|
||||
and rebases the current (uncommitted to SVN) work against it.
|
||||
|
||||
This works similarly to 'svn update' or 'git-pull' except that
|
||||
it preserves linear history with 'git-rebase' instead of
|
||||
'git-merge' for ease of dcommit-ing with git-svn.
|
||||
|
||||
This accepts all options that 'git-svn fetch' and 'git-rebase'
|
||||
accepts. However '--fetch-all' only fetches from the current
|
||||
[svn-remote], and not all [svn-remote] definitions.
|
||||
|
||||
Like 'git-rebase'; this requires that the working tree be clean
|
||||
and have no uncommitted changes.
|
||||
|
||||
'dcommit'::
|
||||
Commit each diff from a specified head directly to the SVN
|
||||
@ -96,16 +149,6 @@ manually joining branches on commit.
|
||||
commit. All merging is assumed to have taken place
|
||||
independently of git-svn functions.
|
||||
|
||||
'rebuild'::
|
||||
Not a part of daily usage, but this is a useful command if
|
||||
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
|
||||
resume fetch operations. A Subversion URL may be optionally
|
||||
specified at the command-line if the directory/repository you're
|
||||
tracking has moved or changed protocols.
|
||||
|
||||
'show-ignore'::
|
||||
Recursively finds and lists the svn:ignore property on
|
||||
directories. The output is suitable for appending to
|
||||
@ -122,53 +165,13 @@ manually joining branches on commit.
|
||||
repository (that has been init-ed with git-svn).
|
||||
The -r<revision> option is required for this.
|
||||
|
||||
'graft-branches'::
|
||||
This command attempts to detect merges/branches from already
|
||||
imported history. Techniques used currently include regexes,
|
||||
file copies, and tree-matches). This command generates (or
|
||||
modifies) the $GIT_DIR/info/grafts file. This command is
|
||||
considered experimental, and inherently flawed because
|
||||
merge-tracking in SVN is inherently flawed and inconsistent
|
||||
across different repositories.
|
||||
|
||||
'multi-init'::
|
||||
This command supports git-svnimport-like command-line syntax for
|
||||
importing repositories that are laid out as recommended by the
|
||||
SVN folks. This is a bit more tolerant than the git-svnimport
|
||||
command-line syntax and doesn't require the user to figure out
|
||||
where the repository URL ends and where the repository path
|
||||
begins.
|
||||
|
||||
-T<trunk_subdir>::
|
||||
--trunk=<trunk_subdir>::
|
||||
-t<tags_subdir>::
|
||||
--tags=<tags_subdir>::
|
||||
-b<branches_subdir>::
|
||||
--branches=<branches_subdir>::
|
||||
These are the command-line options for multi-init. Each of
|
||||
these flags can point to a relative repository path
|
||||
(--tags=project/tags') or a full url
|
||||
(--tags=https://foo.org/project/tags)
|
||||
|
||||
--prefix=<prefix>
|
||||
This allows one to specify a prefix which is prepended to the
|
||||
names of remotes. The prefix does not automatically include a
|
||||
trailing slash, so be sure you include one in the argument if
|
||||
that is what you want. This is useful if you wish to track
|
||||
multiple projects that share a common repository.
|
||||
|
||||
'multi-fetch'::
|
||||
This runs fetch on all known SVN branches we're tracking. This
|
||||
will NOT discover new branches (unlike git-svnimport), so
|
||||
multi-init will need to be re-run (it's idempotent).
|
||||
|
||||
--
|
||||
|
||||
OPTIONS
|
||||
-------
|
||||
--
|
||||
|
||||
--shared::
|
||||
--shared[={false|true|umask|group|all|world|everybody}]::
|
||||
--template=<template_directory>::
|
||||
Only used with the 'init' command.
|
||||
These are passed directly to gitlink:git-init[1].
|
||||
@ -176,14 +179,15 @@ OPTIONS
|
||||
-r <ARG>::
|
||||
--revision <ARG>::
|
||||
|
||||
Only used with the 'fetch' command.
|
||||
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 allows revision ranges for partial/cauterized history
|
||||
to be supported. $NUMBER, $NUMBER1:$NUMBER2 (numeric ranges),
|
||||
$NUMBER:HEAD, and BASE:$NUMBER are all supported.
|
||||
|
||||
This can allow you to make partial mirrors when running fetch.
|
||||
This can allow you to make partial mirrors when running fetch;
|
||||
but is generally not recommended because history will be skipped
|
||||
and lost.
|
||||
|
||||
-::
|
||||
--stdin::
|
||||
@ -270,7 +274,7 @@ config key: svn.repackflags
|
||||
-s<strategy>::
|
||||
--strategy=<strategy>::
|
||||
|
||||
These are only used with the 'dcommit' command.
|
||||
These are only used with the 'dcommit' and 'rebase' commands.
|
||||
|
||||
Passed directly to git-rebase when using 'dcommit' if a
|
||||
'git-reset' cannot be used (see dcommit).
|
||||
@ -289,75 +293,79 @@ ADVANCED OPTIONS
|
||||
----------------
|
||||
--
|
||||
|
||||
-b<refname>::
|
||||
--branch <refname>::
|
||||
Used with 'fetch', 'dcommit' or 'set-tree'.
|
||||
|
||||
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_.
|
||||
|
||||
This option may be specified multiple times, once for each
|
||||
branch.
|
||||
|
||||
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-repos,Tracking Multiple Repositories or Branches>>'
|
||||
for more information on using GIT_SVN_ID.
|
||||
This sets GIT_SVN_ID (instead of using the environment). This
|
||||
allows the user to override the default refname to fetch from
|
||||
when tracking a single URL. The 'log' and 'dcommit' commands
|
||||
no longer require this switch as an argument.
|
||||
|
||||
-R<remote name>::
|
||||
--svn-remote <remote name>::
|
||||
Specify the [svn-remote "<remote name>"] section to use,
|
||||
this allows SVN multiple repositories to be tracked.
|
||||
Default: "svn"
|
||||
|
||||
--follow-parent::
|
||||
This is especially helpful when we're tracking a directory
|
||||
that has been moved around within the repository, or if we
|
||||
started tracking a branch and never tracked the trunk it was
|
||||
descended from.
|
||||
descended from. This feature is enabled by default, use
|
||||
--no-follow-parent to disable it.
|
||||
|
||||
config key: svn.followparent
|
||||
|
||||
--no-metadata::
|
||||
--
|
||||
CONFIG FILE-ONLY OPTIONS
|
||||
------------------------
|
||||
--
|
||||
|
||||
svn.noMetadata::
|
||||
svn-remote.<name>.noMetadata::
|
||||
This gets rid of the git-svn-id: lines at the end of every commit.
|
||||
|
||||
With this, you lose the ability to use the rebuild command. If
|
||||
you ever lose your .git/svn/git-svn/.rev_db file, you won't be
|
||||
able to fetch again, either. This is fine for one-shot imports.
|
||||
If you lose your .git/svn/git-svn/.rev_db file, git-svn will not
|
||||
be able to rebuild it and you won't be able to fetch again,
|
||||
either. This is fine for one-shot imports.
|
||||
|
||||
The 'git-svn log' command will not work on repositories using this,
|
||||
either.
|
||||
The 'git-svn log' command will not work on repositories using
|
||||
this, either. Using this conflicts with the 'useSvmProps'
|
||||
option for (hopefully) obvious reasons.
|
||||
|
||||
config key: svn.nometadata
|
||||
svn.useSvmProps::
|
||||
svn-remote.<name>.useSvmProps::
|
||||
This allows git-svn to re-map repository URLs and UUIDs from
|
||||
mirrors created using SVN::Mirror (or svk) for metadata.
|
||||
|
||||
--
|
||||
If an SVN revision has a property, "svm:headrev", it is likely
|
||||
that the revision was created by SVN::Mirror (also used by SVK).
|
||||
The property contains a repository UUID and a revision. We want
|
||||
to make it look like we are mirroring the original URL, so
|
||||
introduce a helper function that returns the original identity
|
||||
URL and UUID, and use it when generating metadata in commit
|
||||
messages.
|
||||
|
||||
COMPATIBILITY OPTIONS
|
||||
---------------------
|
||||
--
|
||||
svn.useSvnsyncProps::
|
||||
svn-remote.<name>.useSvnsyncprops::
|
||||
Similar to the useSvmProps option; this is for users
|
||||
of the svnsync(1) command distributed with SVN 1.4.x and
|
||||
later.
|
||||
|
||||
--upgrade::
|
||||
Only used with the 'rebuild' command.
|
||||
svn-remote.<name>.rewriteRoot::
|
||||
This allows users to create repositories from alternate
|
||||
URLs. For example, an administrator could run git-svn on the
|
||||
server locally (accessing via file://) but wish to distribute
|
||||
the repository with a public http:// or svn:// URL in the
|
||||
metadata so users of it will see the public URL.
|
||||
|
||||
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.
|
||||
Since the noMetadata, rewriteRoot, useSvnsyncProps and useSvmProps
|
||||
options all affect the metadata generated and used by git-svn; they
|
||||
*must* be set in the configuration file before any history is imported
|
||||
and these settings should never be changed once they are set.
|
||||
|
||||
--ignore-nodate::
|
||||
Only used with the 'fetch' command.
|
||||
|
||||
By default git-svn will crash if it tries to import a revision
|
||||
from SVN which has '(no date)' listed as the date of the revision.
|
||||
This is repository corruption on SVN's part, plain and simple.
|
||||
But sometimes you really need those revisions anyway.
|
||||
|
||||
If supplied git-svn will convert '(no date)' entries to the UNIX
|
||||
epoch (midnight on Jan. 1, 1970). Yes, that's probably very wrong.
|
||||
SVN was very wrong.
|
||||
Additionally, only one of these four options can be used per-svn-remote
|
||||
section because they affect the 'git-svn-id:' metadata line.
|
||||
|
||||
--
|
||||
|
||||
@ -367,43 +375,37 @@ Basic Examples
|
||||
Tracking and contributing to a the trunk of a Subversion-managed project:
|
||||
|
||||
------------------------------------------------------------------------
|
||||
# Initialize a repo (like git init):
|
||||
git-svn init http://svn.foo.org/project/trunk
|
||||
# Fetch remote revisions:
|
||||
git-svn fetch
|
||||
# Create your own branch to hack on:
|
||||
git checkout -b my-branch remotes/git-svn
|
||||
# Do some work, and then commit your new changes to SVN, as well as
|
||||
# automatically updating your working HEAD:
|
||||
# Clone a repo (like git clone):
|
||||
git-svn clone http://svn.foo.org/project/trunk
|
||||
# Enter the newly cloned directory:
|
||||
cd trunk
|
||||
# You should be on master branch, double-check with git-branch
|
||||
git branch
|
||||
# Do some work and commit locally to git:
|
||||
git commit ...
|
||||
# Something is committed to SVN, rebase your local changes against the
|
||||
# latest changes in SVN:
|
||||
git-svn rebase
|
||||
# Now commit your changes (that were committed previously using git) to SVN,
|
||||
# as well as automatically updating your working HEAD:
|
||||
git-svn dcommit
|
||||
# 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
|
||||
------------------------------------------------------------------------
|
||||
|
||||
Tracking and contributing to an entire Subversion-managed project
|
||||
(complete with a trunk, tags and branches):
|
||||
See also:
|
||||
'<<tracking-multiple-repos,Tracking Multiple Repositories or Branches>>'
|
||||
|
||||
------------------------------------------------------------------------
|
||||
# Initialize a repo (like git init):
|
||||
git-svn multi-init http://svn.foo.org/project \
|
||||
-T trunk -b branches -t tags
|
||||
# Fetch remote revisions:
|
||||
git-svn multi-fetch
|
||||
# Create your own branch of trunk to hack on:
|
||||
git checkout -b my-trunk remotes/trunk
|
||||
# Do some work, and then commit your new changes to SVN, as well as
|
||||
# automatically updating your working HEAD:
|
||||
git-svn dcommit -i trunk
|
||||
# Something has been committed to trunk, rebase the latest into your branch:
|
||||
git-svn multi-fetch && git rebase remotes/trunk
|
||||
# Append svn:ignore settings of trunk to the default git exclude file:
|
||||
git-svn show-ignore -i trunk >> .git/info/exclude
|
||||
# Check for new branches and tags (no arguments are needed):
|
||||
git-svn multi-init
|
||||
# Clone a repo (like git clone):
|
||||
git-svn clone http://svn.foo.org/project -T trunk -b branches -t tags
|
||||
# View all branches and tags you have cloned:
|
||||
git branch -r
|
||||
# Reset your master to trunk (or any other branch, replacing 'trunk'
|
||||
# with the appropriate name):
|
||||
git reset --hard remotes/trunk
|
||||
# You may only dcommit to one branch/tag/trunk at a time. The usage
|
||||
# of dcommit/rebase/show-ignore should be teh same as above.
|
||||
------------------------------------------------------------------------
|
||||
|
||||
REBASE VS. PULL/MERGE
|
||||
@ -416,7 +418,7 @@ pulled or merged from. This is because the author favored
|
||||
|
||||
If you use 'git-svn set-tree 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' or
|
||||
use 'git-svn rebase' to update your work branch instead of 'git pull' or
|
||||
'git merge'. 'pull/merge' can cause non-linear history to be flattened
|
||||
when committing into SVN, which can lead to merge commits reversing
|
||||
previous commits in SVN.
|
||||
@ -426,67 +428,49 @@ DESIGN PHILOSOPHY
|
||||
Merge tracking in Subversion is lacking and doing branched development
|
||||
with Subversion is cumbersome as a result. git-svn does not do
|
||||
automated merge/branch tracking by default and leaves it entirely up to
|
||||
the user on the git side.
|
||||
|
||||
[[tracking-multiple-repos]]
|
||||
TRACKING MULTIPLE REPOSITORIES OR BRANCHES
|
||||
------------------------------------------
|
||||
Because git-svn does not care about relationships between different
|
||||
branches or directories in a Subversion repository, git-svn has a simple
|
||||
hack to allow it to track an arbitrary number of related _or_ unrelated
|
||||
SVN repositories via one git repository. Simply use the --id/-i flag or
|
||||
set the GIT_SVN_ID environment variable to a name other other than
|
||||
"git-svn" (the default) and git-svn will ignore the contents of the
|
||||
$GIT_DIR/svn/git-svn directory and instead do all of its work in
|
||||
$GIT_DIR/svn/$GIT_SVN_ID for that 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.
|
||||
|
||||
Unfetched SVN revisions may be imported as children of existing commits
|
||||
by specifying additional arguments to 'fetch'. Additional parents may
|
||||
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:
|
||||
|
||||
------------------------------------------------
|
||||
git-svn fetch 375=$(git-rev-parse HEAD)
|
||||
------------------------------------------------
|
||||
|
||||
If you're tracking a directory that has moved, or otherwise been
|
||||
branched or tagged off of another directory in the repository and you
|
||||
care about the full history of the project, then you can use
|
||||
the --follow-parent option.
|
||||
|
||||
------------------------------------------------
|
||||
git-svn fetch --follow-parent
|
||||
------------------------------------------------
|
||||
the user on the git side. git-svn does however follow copy
|
||||
history of the directory that it is tracking, however (much like
|
||||
how 'svn log' works).
|
||||
|
||||
BUGS
|
||||
----
|
||||
|
||||
We ignore all SVN properties except svn:executable. Too difficult to
|
||||
map them since we rely heavily on git write-tree being _exactly_ the
|
||||
same on both the SVN and git working trees and I prefer not to clutter
|
||||
working trees with metadata files.
|
||||
We ignore all SVN properties except svn:executable. Any unhandled
|
||||
properties are logged to $GIT_DIR/svn/<refname>/unhandled.log
|
||||
|
||||
Renamed and copied directories are not detected by git and hence not
|
||||
tracked when committing to SVN. I do not plan on adding support for
|
||||
this as it's quite difficult and time-consuming to get working for all
|
||||
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.
|
||||
the possible corner cases (git doesn't do it, either). Committing
|
||||
renamed and copied files are fully supported if they're similar enough
|
||||
for git to detect them.
|
||||
|
||||
CONFIGURATION
|
||||
-------------
|
||||
|
||||
git-svn stores [svn-remote] configuration information in the
|
||||
repository .git/config file. It is similar the core git
|
||||
[remote] sections except 'fetch' keys do not accept glob
|
||||
arguments; but they are instead handled by the 'branches'
|
||||
and 'tags' keys. Since some SVN repositories are oddly
|
||||
configured with multiple projects glob expansions such those
|
||||
listed below are allowed:
|
||||
|
||||
------------------------------------------------------------------------
|
||||
[svn-remote "project-a"]
|
||||
url = http://server.org/svn
|
||||
branches = branches/*/project-a:refs/remotes/project-a/branches/*
|
||||
tags = tags/*/project-a:refs/remotes/project-a/tags/*
|
||||
trunk = trunk/project-a:refs/remotes/project-a/trunk
|
||||
------------------------------------------------------------------------
|
||||
|
||||
Keep in mind that the '*' (asterisk) wildcard of the local ref
|
||||
(left of the ':') *must* be the farthest right path component;
|
||||
however the remote wildcard may be anywhere as long as it's own
|
||||
independent path componet (surrounded by '/' or EOL). This
|
||||
type of configuration is not automatically created by 'init' and
|
||||
should be manually entered with a text-editor or using
|
||||
gitlink:git-config[1]
|
||||
|
||||
SEE ALSO
|
||||
--------
|
||||
|
@ -35,6 +35,12 @@ ifdef::stalenotes[]
|
||||
You are reading the documentation for the latest version of git.
|
||||
Documentation for older releases are available here:
|
||||
|
||||
* link:v1.5.0.2/git.html[documentation for release 1.5.0.2]
|
||||
|
||||
* link:v1.5.0.2/RelNotes-1.5.0.2.txt[release notes for 1.5.0.2]
|
||||
|
||||
* link:v1.5.0.1/RelNotes-1.5.0.1.txt[release notes for 1.5.0.1]
|
||||
|
||||
* link:v1.5.0/git.html[documentation for release 1.5.0]
|
||||
|
||||
* link:v1.5.0/RelNotes-1.5.0.txt[release notes for 1.5.0]
|
||||
|
29
Makefile
29
Makefile
@ -28,6 +28,10 @@ all::
|
||||
#
|
||||
# Define NO_STRLCPY if you don't have strlcpy.
|
||||
#
|
||||
# Define NO_STRTOUMAX if you don't have strtoumax in the C library.
|
||||
# If your compiler also does not support long long or does not have
|
||||
# strtoull, define NO_STRTOULL.
|
||||
#
|
||||
# Define NO_SETENV if you don't have setenv in the C library.
|
||||
#
|
||||
# Define NO_SYMLINK_HEAD if you never want .git/HEAD to be a symbolic link.
|
||||
@ -124,6 +128,7 @@ prefix = $(HOME)
|
||||
bindir = $(prefix)/bin
|
||||
gitexecdir = $(bindir)
|
||||
template_dir = $(prefix)/share/git-core/templates/
|
||||
ETC_GITCONFIG = $(prefix)/etc/gitconfig
|
||||
# DESTDIR=
|
||||
|
||||
# default configuration for gitweb
|
||||
@ -262,7 +267,8 @@ LIB_OBJS = \
|
||||
revision.o pager.o tree-walk.o xdiff-interface.o \
|
||||
write_or_die.o trace.o list-objects.o grep.o \
|
||||
alloc.o merge-file.o path-list.o help.o unpack-trees.o $(DIFF_OBJS) \
|
||||
color.o wt-status.o archive-zip.o archive-tar.o shallow.o utf8.o
|
||||
color.o wt-status.o archive-zip.o archive-tar.o shallow.o utf8.o \
|
||||
convert.o
|
||||
|
||||
BUILTIN_OBJS = \
|
||||
builtin-add.o \
|
||||
@ -353,11 +359,13 @@ ifeq ($(uname_S),SunOS)
|
||||
NO_UNSETENV = YesPlease
|
||||
NO_SETENV = YesPlease
|
||||
NO_C99_FORMAT = YesPlease
|
||||
NO_STRTOUMAX = YesPlease
|
||||
endif
|
||||
ifeq ($(uname_R),5.9)
|
||||
NO_UNSETENV = YesPlease
|
||||
NO_SETENV = YesPlease
|
||||
NO_C99_FORMAT = YesPlease
|
||||
NO_STRTOUMAX = YesPlease
|
||||
endif
|
||||
INSTALL = ginstall
|
||||
TAR = gtar
|
||||
@ -517,6 +525,13 @@ ifdef NO_STRLCPY
|
||||
COMPAT_CFLAGS += -DNO_STRLCPY
|
||||
COMPAT_OBJS += compat/strlcpy.o
|
||||
endif
|
||||
ifdef NO_STRTOUMAX
|
||||
COMPAT_CFLAGS += -DNO_STRTOUMAX
|
||||
COMPAT_OBJS += compat/strtoumax.o
|
||||
endif
|
||||
ifdef NO_STRTOULL
|
||||
COMPAT_CFLAGS += -DNO_STRTOULL
|
||||
endif
|
||||
ifdef NO_SETENV
|
||||
COMPAT_CFLAGS += -DNO_SETENV
|
||||
COMPAT_OBJS += compat/setenv.o
|
||||
@ -584,6 +599,7 @@ endif
|
||||
# Shell quote (do not use $(call) to accommodate ancient setups);
|
||||
|
||||
SHA1_HEADER_SQ = $(subst ','\'',$(SHA1_HEADER))
|
||||
ETC_GITCONFIG_SQ = $(subst ','\'',$(ETC_GITCONFIG))
|
||||
|
||||
DESTDIR_SQ = $(subst ','\'',$(DESTDIR))
|
||||
bindir_SQ = $(subst ','\'',$(bindir))
|
||||
@ -596,7 +612,8 @@ PERL_PATH_SQ = $(subst ','\'',$(PERL_PATH))
|
||||
|
||||
LIBS = $(GITLIBS) $(EXTLIBS)
|
||||
|
||||
BASIC_CFLAGS += -DSHA1_HEADER='$(SHA1_HEADER_SQ)' $(COMPAT_CFLAGS)
|
||||
BASIC_CFLAGS += -DSHA1_HEADER='$(SHA1_HEADER_SQ)' \
|
||||
-DETC_GITCONFIG='"$(ETC_GITCONFIG_SQ)"' $(COMPAT_CFLAGS)
|
||||
LIB_OBJS += $(COMPAT_OBJS)
|
||||
|
||||
ALL_CFLAGS += $(BASIC_CFLAGS)
|
||||
@ -812,7 +829,7 @@ GIT-CFLAGS: .FORCE-GIT-CFLAGS
|
||||
|
||||
export NO_SVN_TESTS
|
||||
|
||||
test: all
|
||||
test: all test-chmtime$X
|
||||
$(MAKE) -C t/ all
|
||||
|
||||
test-date$X: test-date.c date.o ctype.o
|
||||
@ -827,6 +844,9 @@ test-dump-cache-tree$X: dump-cache-tree.o $(GITLIBS)
|
||||
test-sha1$X: test-sha1.o $(GITLIBS)
|
||||
$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(LIBS)
|
||||
|
||||
test-chmtime$X: test-chmtime.c
|
||||
$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $<
|
||||
|
||||
check-sha1:: test-sha1$X
|
||||
./test-sha1.sh
|
||||
|
||||
@ -882,7 +902,8 @@ dist: git.spec git-archive
|
||||
$(TAR) rf $(GIT_TARNAME).tar \
|
||||
$(GIT_TARNAME)/git.spec \
|
||||
$(GIT_TARNAME)/version \
|
||||
$(GIT_TARNAME)/git-gui/version
|
||||
$(GIT_TARNAME)/git-gui/version \
|
||||
$(GIT_TARNAME)/git-gui/credits
|
||||
@rm -rf $(GIT_TARNAME)
|
||||
gzip -f -9 $(GIT_TARNAME).tar
|
||||
|
||||
|
174
builtin-apply.c
174
builtin-apply.c
@ -28,6 +28,7 @@ static int newfd = -1;
|
||||
|
||||
static int unidiff_zero;
|
||||
static int p_value = 1;
|
||||
static int p_value_known;
|
||||
static int check_index;
|
||||
static int write_index;
|
||||
static int cached;
|
||||
@ -144,6 +145,7 @@ struct patch {
|
||||
unsigned long deflate_origlen;
|
||||
int lines_added, lines_deleted;
|
||||
int score;
|
||||
unsigned int is_toplevel_relative:1;
|
||||
unsigned int inaccurate_eof:1;
|
||||
unsigned int is_binary:1;
|
||||
unsigned int is_copy:1;
|
||||
@ -238,7 +240,7 @@ static int name_terminate(const char *name, int namelen, int c, int terminate)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static char * find_name(const char *line, char *def, int p_value, int terminate)
|
||||
static char *find_name(const char *line, char *def, int p_value, int terminate)
|
||||
{
|
||||
int len;
|
||||
const char *start = line;
|
||||
@ -311,11 +313,54 @@ static char * find_name(const char *line, char *def, int p_value, int terminate)
|
||||
return name;
|
||||
}
|
||||
|
||||
static int count_slashes(const char *cp)
|
||||
{
|
||||
int cnt = 0;
|
||||
char ch;
|
||||
|
||||
while ((ch = *cp++))
|
||||
if (ch == '/')
|
||||
cnt++;
|
||||
return cnt;
|
||||
}
|
||||
|
||||
/*
|
||||
* Given the string after "--- " or "+++ ", guess the appropriate
|
||||
* p_value for the given patch.
|
||||
*/
|
||||
static int guess_p_value(const char *nameline)
|
||||
{
|
||||
char *name, *cp;
|
||||
int val = -1;
|
||||
|
||||
if (is_dev_null(nameline))
|
||||
return -1;
|
||||
name = find_name(nameline, NULL, 0, TERM_SPACE | TERM_TAB);
|
||||
if (!name)
|
||||
return -1;
|
||||
cp = strchr(name, '/');
|
||||
if (!cp)
|
||||
val = 0;
|
||||
else if (prefix) {
|
||||
/*
|
||||
* Does it begin with "a/$our-prefix" and such? Then this is
|
||||
* very likely to apply to our directory.
|
||||
*/
|
||||
if (!strncmp(name, prefix, prefix_length))
|
||||
val = count_slashes(prefix);
|
||||
else {
|
||||
cp++;
|
||||
if (!strncmp(cp, prefix, prefix_length))
|
||||
val = count_slashes(prefix) + 1;
|
||||
}
|
||||
}
|
||||
free(name);
|
||||
return val;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the name etc info from the --/+++ lines of a traditional patch header
|
||||
*
|
||||
* NOTE! This hardcodes "-p1" behaviour in filename detection.
|
||||
*
|
||||
* FIXME! The end-of-filename heuristics are kind of screwy. For existing
|
||||
* files, we can happily check the index for a match, but for creating a
|
||||
* new file we should try to match whatever "patch" does. I have no idea.
|
||||
@ -326,6 +371,16 @@ static void parse_traditional_patch(const char *first, const char *second, struc
|
||||
|
||||
first += 4; /* skip "--- " */
|
||||
second += 4; /* skip "+++ " */
|
||||
if (!p_value_known) {
|
||||
int p, q;
|
||||
p = guess_p_value(first);
|
||||
q = guess_p_value(second);
|
||||
if (p < 0) p = q;
|
||||
if (0 <= p && p == q) {
|
||||
p_value = p;
|
||||
p_value_known = 1;
|
||||
}
|
||||
}
|
||||
if (is_dev_null(first)) {
|
||||
patch->is_new = 1;
|
||||
patch->is_delete = 0;
|
||||
@ -787,6 +842,7 @@ static int find_header(char *line, unsigned long size, int *hdrsize, struct patc
|
||||
{
|
||||
unsigned long offset, len;
|
||||
|
||||
patch->is_toplevel_relative = 0;
|
||||
patch->is_rename = patch->is_copy = 0;
|
||||
patch->is_new = patch->is_delete = -1;
|
||||
patch->old_mode = patch->new_mode = 0;
|
||||
@ -831,6 +887,7 @@ static int find_header(char *line, unsigned long size, int *hdrsize, struct patc
|
||||
die("git diff header lacks filename information (line %d)", linenr);
|
||||
patch->old_name = patch->new_name = patch->def_name;
|
||||
}
|
||||
patch->is_toplevel_relative = 1;
|
||||
*hdrsize = git_hdr_len;
|
||||
return offset;
|
||||
}
|
||||
@ -1129,11 +1186,11 @@ static struct fragment *parse_binary_hunk(char **buf_p,
|
||||
|
||||
*status_p = 0;
|
||||
|
||||
if (!strncmp(buffer, "delta ", 6)) {
|
||||
if (!prefixcmp(buffer, "delta ")) {
|
||||
patch_method = BINARY_DELTA_DEFLATED;
|
||||
origlen = strtoul(buffer + 6, NULL, 10);
|
||||
}
|
||||
else if (!strncmp(buffer, "literal ", 8)) {
|
||||
else if (!prefixcmp(buffer, "literal ")) {
|
||||
patch_method = BINARY_LITERAL_DEFLATED;
|
||||
origlen = strtoul(buffer + 8, NULL, 10);
|
||||
}
|
||||
@ -1393,28 +1450,39 @@ static void show_stats(struct patch *patch)
|
||||
free(qname);
|
||||
}
|
||||
|
||||
static int read_old_data(struct stat *st, const char *path, void *buf, unsigned long size)
|
||||
static int read_old_data(struct stat *st, const char *path, char **buf_p, unsigned long *alloc_p, unsigned long *size_p)
|
||||
{
|
||||
int fd;
|
||||
unsigned long got;
|
||||
unsigned long nsize;
|
||||
char *nbuf;
|
||||
unsigned long size = *size_p;
|
||||
char *buf = *buf_p;
|
||||
|
||||
switch (st->st_mode & S_IFMT) {
|
||||
case S_IFLNK:
|
||||
return readlink(path, buf, size);
|
||||
return readlink(path, buf, size) != size;
|
||||
case S_IFREG:
|
||||
fd = open(path, O_RDONLY);
|
||||
if (fd < 0)
|
||||
return error("unable to open %s", path);
|
||||
got = 0;
|
||||
for (;;) {
|
||||
int ret = xread(fd, (char *) buf + got, size - got);
|
||||
int ret = xread(fd, buf + got, size - got);
|
||||
if (ret <= 0)
|
||||
break;
|
||||
got += ret;
|
||||
}
|
||||
close(fd);
|
||||
return got;
|
||||
|
||||
nsize = got;
|
||||
nbuf = buf;
|
||||
if (convert_to_git(path, &nbuf, &nsize)) {
|
||||
free(buf);
|
||||
*buf_p = nbuf;
|
||||
*alloc_p = nsize;
|
||||
*size_p = nsize;
|
||||
}
|
||||
return got != size;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
@ -1655,6 +1723,8 @@ static int apply_one_fragment(struct buffer_desc *desc, struct fragment *frag, i
|
||||
/* Ignore it, we already handled it */
|
||||
break;
|
||||
default:
|
||||
if (apply_verbosely)
|
||||
error("invalid start of line: '%c'", first);
|
||||
return -1;
|
||||
}
|
||||
patch += len;
|
||||
@ -1752,6 +1822,9 @@ static int apply_one_fragment(struct buffer_desc *desc, struct fragment *frag, i
|
||||
}
|
||||
}
|
||||
|
||||
if (offset && apply_verbosely)
|
||||
error("while searching for:\n%.*s", oldsize, oldlines);
|
||||
|
||||
free(old);
|
||||
free(new);
|
||||
return offset;
|
||||
@ -1910,7 +1983,7 @@ static int apply_data(struct patch *patch, struct stat *st, struct cache_entry *
|
||||
size = st->st_size;
|
||||
alloc = size + 8192;
|
||||
buf = xmalloc(alloc);
|
||||
if (read_old_data(st, patch->old_name, buf, alloc) != size)
|
||||
if (read_old_data(st, patch->old_name, &buf, &alloc, &size))
|
||||
return error("read of %s failed", patch->old_name);
|
||||
}
|
||||
|
||||
@ -2232,7 +2305,7 @@ static void patch_stats(struct patch *patch)
|
||||
}
|
||||
}
|
||||
|
||||
static void remove_file(struct patch *patch)
|
||||
static void remove_file(struct patch *patch, int rmdir_empty)
|
||||
{
|
||||
if (write_index) {
|
||||
if (remove_file_from_cache(patch->old_name) < 0)
|
||||
@ -2240,7 +2313,7 @@ static void remove_file(struct patch *patch)
|
||||
cache_tree_invalidate_path(active_cache_tree, patch->old_name);
|
||||
}
|
||||
if (!cached) {
|
||||
if (!unlink(patch->old_name)) {
|
||||
if (!unlink(patch->old_name) && rmdir_empty) {
|
||||
char *name = xstrdup(patch->old_name);
|
||||
char *end = strrchr(name, '/');
|
||||
while (end) {
|
||||
@ -2282,12 +2355,22 @@ static void add_index_file(const char *path, unsigned mode, void *buf, unsigned
|
||||
static int try_create_file(const char *path, unsigned int mode, const char *buf, unsigned long size)
|
||||
{
|
||||
int fd;
|
||||
char *nbuf;
|
||||
unsigned long nsize;
|
||||
|
||||
if (S_ISLNK(mode))
|
||||
/* Although buf:size is counted string, it also is NUL
|
||||
* terminated.
|
||||
*/
|
||||
return symlink(buf, path);
|
||||
nsize = size;
|
||||
nbuf = (char *) buf;
|
||||
if (convert_to_working_tree(path, &nbuf, &nsize)) {
|
||||
free((char *) buf);
|
||||
buf = nbuf;
|
||||
size = nsize;
|
||||
}
|
||||
|
||||
fd = open(path, O_CREAT | O_EXCL | O_WRONLY, (mode & 0100) ? 0777 : 0666);
|
||||
if (fd < 0)
|
||||
return -1;
|
||||
@ -2373,7 +2456,7 @@ static void write_out_one_result(struct patch *patch, int phase)
|
||||
{
|
||||
if (patch->is_delete > 0) {
|
||||
if (phase == 0)
|
||||
remove_file(patch);
|
||||
remove_file(patch, 1);
|
||||
return;
|
||||
}
|
||||
if (patch->is_new > 0 || patch->is_copy) {
|
||||
@ -2386,7 +2469,7 @@ static void write_out_one_result(struct patch *patch, int phase)
|
||||
* thing: remove the old, write the new
|
||||
*/
|
||||
if (phase == 0)
|
||||
remove_file(patch);
|
||||
remove_file(patch, 0);
|
||||
if (phase == 1)
|
||||
create_file(patch);
|
||||
}
|
||||
@ -2508,6 +2591,32 @@ static int use_patch(struct patch *p)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void prefix_one(char **name)
|
||||
{
|
||||
char *old_name = *name;
|
||||
if (!old_name)
|
||||
return;
|
||||
*name = xstrdup(prefix_filename(prefix, prefix_length, *name));
|
||||
free(old_name);
|
||||
}
|
||||
|
||||
static void prefix_patches(struct patch *p)
|
||||
{
|
||||
if (!prefix || p->is_toplevel_relative)
|
||||
return;
|
||||
for ( ; p; p = p->next) {
|
||||
if (p->new_name == p->old_name) {
|
||||
char *prefixed = p->new_name;
|
||||
prefix_one(&prefixed);
|
||||
p->new_name = p->old_name = prefixed;
|
||||
}
|
||||
else {
|
||||
prefix_one(&p->new_name);
|
||||
prefix_one(&p->old_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int apply_patch(int fd, const char *filename, int inaccurate_eof)
|
||||
{
|
||||
unsigned long offset, size;
|
||||
@ -2530,11 +2639,14 @@ static int apply_patch(int fd, const char *filename, int inaccurate_eof)
|
||||
break;
|
||||
if (apply_in_reverse)
|
||||
reverse_patches(patch);
|
||||
if (prefix)
|
||||
prefix_patches(patch);
|
||||
if (use_patch(patch)) {
|
||||
patch_stats(patch);
|
||||
*listp = patch;
|
||||
listp = &patch->next;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
/* perhaps free it a bit better? */
|
||||
free(patch);
|
||||
skipped_patch++;
|
||||
@ -2595,9 +2707,16 @@ int cmd_apply(int argc, const char **argv, const char *unused_prefix)
|
||||
int read_stdin = 1;
|
||||
int inaccurate_eof = 0;
|
||||
int errs = 0;
|
||||
int is_not_gitdir = 0;
|
||||
|
||||
const char *whitespace_option = NULL;
|
||||
|
||||
prefix = setup_git_directory_gently(&is_not_gitdir);
|
||||
prefix_length = prefix ? strlen(prefix) : 0;
|
||||
git_config(git_apply_config);
|
||||
if (apply_default_whitespace)
|
||||
parse_whitespace_option(apply_default_whitespace);
|
||||
|
||||
for (i = 1; i < argc; i++) {
|
||||
const char *arg = argv[i];
|
||||
char *end;
|
||||
@ -2608,15 +2727,16 @@ int cmd_apply(int argc, const char **argv, const char *unused_prefix)
|
||||
read_stdin = 0;
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(arg, "--exclude=", 10)) {
|
||||
if (!prefixcmp(arg, "--exclude=")) {
|
||||
struct excludes *x = xmalloc(sizeof(*x));
|
||||
x->path = arg + 10;
|
||||
x->next = excludes;
|
||||
excludes = x;
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(arg, "-p", 2)) {
|
||||
if (!prefixcmp(arg, "-p")) {
|
||||
p_value = atoi(arg + 2);
|
||||
p_value_known = 1;
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(arg, "--no-add")) {
|
||||
@ -2648,10 +2768,14 @@ int cmd_apply(int argc, const char **argv, const char *unused_prefix)
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(arg, "--index")) {
|
||||
if (is_not_gitdir)
|
||||
die("--index outside a repository");
|
||||
check_index = 1;
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(arg, "--cached")) {
|
||||
if (is_not_gitdir)
|
||||
die("--cached outside a repository");
|
||||
check_index = 1;
|
||||
cached = 1;
|
||||
continue;
|
||||
@ -2669,13 +2793,13 @@ int cmd_apply(int argc, const char **argv, const char *unused_prefix)
|
||||
line_termination = 0;
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(arg, "-C", 2)) {
|
||||
if (!prefixcmp(arg, "-C")) {
|
||||
p_context = strtoul(arg + 2, &end, 0);
|
||||
if (*end != '\0')
|
||||
die("unrecognized context count '%s'", arg + 2);
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(arg, "--whitespace=", 13)) {
|
||||
if (!prefixcmp(arg, "--whitespace=")) {
|
||||
whitespace_option = arg + 13;
|
||||
parse_whitespace_option(arg + 13);
|
||||
continue;
|
||||
@ -2692,7 +2816,7 @@ int cmd_apply(int argc, const char **argv, const char *unused_prefix)
|
||||
apply = apply_with_reject = apply_verbosely = 1;
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(arg, "--verbose")) {
|
||||
if (!strcmp(arg, "-v") || !strcmp(arg, "--verbose")) {
|
||||
apply_verbosely = 1;
|
||||
continue;
|
||||
}
|
||||
@ -2700,14 +2824,6 @@ int cmd_apply(int argc, const char **argv, const char *unused_prefix)
|
||||
inaccurate_eof = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (check_index && prefix_length < 0) {
|
||||
prefix = setup_git_directory();
|
||||
prefix_length = prefix ? strlen(prefix) : 0;
|
||||
git_config(git_apply_config);
|
||||
if (!whitespace_option && apply_default_whitespace)
|
||||
parse_whitespace_option(apply_default_whitespace);
|
||||
}
|
||||
if (0 < prefix_length)
|
||||
arg = prefix_filename(prefix, prefix_length, arg);
|
||||
|
||||
|
@ -35,7 +35,7 @@ static int run_remote_archiver(const char *remote, int argc,
|
||||
|
||||
for (i = 1; i < argc; i++) {
|
||||
const char *arg = argv[i];
|
||||
if (!strncmp("--exec=", arg, 7)) {
|
||||
if (!prefixcmp(arg, "--exec=")) {
|
||||
if (exec_at)
|
||||
die("multiple --exec specified");
|
||||
exec = arg + 7;
|
||||
@ -62,7 +62,7 @@ static int run_remote_archiver(const char *remote, int argc,
|
||||
if (buf[len-1] == '\n')
|
||||
buf[--len] = 0;
|
||||
if (strcmp(buf, "ACK")) {
|
||||
if (len > 5 && !strncmp(buf, "NACK ", 5))
|
||||
if (len > 5 && !prefixcmp(buf, "NACK "))
|
||||
die("git-archive: NACK %s", buf + 5);
|
||||
die("git-archive: protocol error");
|
||||
}
|
||||
@ -166,11 +166,11 @@ int parse_archive_args(int argc, const char **argv, struct archiver *ar)
|
||||
verbose = 1;
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(arg, "--format=", 9)) {
|
||||
if (!prefixcmp(arg, "--format=")) {
|
||||
format = arg + 9;
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(arg, "--prefix=", 9)) {
|
||||
if (!prefixcmp(arg, "--prefix=")) {
|
||||
base = arg + 9;
|
||||
continue;
|
||||
}
|
||||
@ -218,7 +218,7 @@ static const char *extract_remote_arg(int *ac, const char **av)
|
||||
if (!strcmp(arg, "--"))
|
||||
no_more_options = 1;
|
||||
if (!no_more_options) {
|
||||
if (!strncmp(arg, "--remote=", 9)) {
|
||||
if (!prefixcmp(arg, "--remote=")) {
|
||||
if (remote)
|
||||
die("Multiple --remote specified");
|
||||
remote = arg + 9;
|
||||
|
@ -2097,17 +2097,17 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
|
||||
output_option |= OUTPUT_LONG_OBJECT_NAME;
|
||||
else if (!strcmp("-S", arg) && ++i < argc)
|
||||
revs_file = argv[i];
|
||||
else if (!strncmp("-M", arg, 2)) {
|
||||
else if (!prefixcmp(arg, "-M")) {
|
||||
opt |= PICKAXE_BLAME_MOVE;
|
||||
blame_move_score = parse_score(arg+2);
|
||||
}
|
||||
else if (!strncmp("-C", arg, 2)) {
|
||||
else if (!prefixcmp(arg, "-C")) {
|
||||
if (opt & PICKAXE_BLAME_COPY)
|
||||
opt |= PICKAXE_BLAME_COPY_HARDER;
|
||||
opt |= PICKAXE_BLAME_COPY | PICKAXE_BLAME_MOVE;
|
||||
blame_copy_score = parse_score(arg+2);
|
||||
}
|
||||
else if (!strncmp("-L", arg, 2)) {
|
||||
else if (!prefixcmp(arg, "-L")) {
|
||||
if (!arg[2]) {
|
||||
if (++i >= argc)
|
||||
usage(blame_usage);
|
||||
|
@ -59,7 +59,7 @@ int git_branch_config(const char *var, const char *value)
|
||||
branch_use_color = git_config_colorbool(var, value);
|
||||
return 0;
|
||||
}
|
||||
if (!strncmp(var, "color.branch.", 13)) {
|
||||
if (!prefixcmp(var, "color.branch.")) {
|
||||
int slot = parse_branch_color_slot(var, 13);
|
||||
color_parse(value, var, branch_colors[slot]);
|
||||
return 0;
|
||||
@ -178,13 +178,13 @@ static int append_ref(const char *refname, const unsigned char *sha1, int flags,
|
||||
int len;
|
||||
|
||||
/* Detect kind */
|
||||
if (!strncmp(refname, "refs/heads/", 11)) {
|
||||
if (!prefixcmp(refname, "refs/heads/")) {
|
||||
kind = REF_LOCAL_BRANCH;
|
||||
refname += 11;
|
||||
} else if (!strncmp(refname, "refs/remotes/", 13)) {
|
||||
} else if (!prefixcmp(refname, "refs/remotes/")) {
|
||||
kind = REF_REMOTE_BRANCH;
|
||||
refname += 13;
|
||||
} else if (!strncmp(refname, "refs/tags/", 10)) {
|
||||
} else if (!prefixcmp(refname, "refs/tags/")) {
|
||||
kind = REF_TAG;
|
||||
refname += 10;
|
||||
}
|
||||
@ -446,7 +446,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
|
||||
reflog = 1;
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(arg, "--abbrev=", 9)) {
|
||||
if (!prefixcmp(arg, "--abbrev=")) {
|
||||
abbrev = atoi(arg+9);
|
||||
continue;
|
||||
}
|
||||
@ -476,7 +476,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
|
||||
detached = 1;
|
||||
}
|
||||
else {
|
||||
if (strncmp(head, "refs/heads/", 11))
|
||||
if (prefixcmp(head, "refs/heads/"))
|
||||
die("HEAD not found below refs/heads!");
|
||||
head += 11;
|
||||
}
|
||||
|
@ -223,12 +223,12 @@ int cmd_checkout_index(int argc, const char **argv, const char *prefix)
|
||||
to_tempfile = 1;
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(arg, "--prefix=", 9)) {
|
||||
if (!prefixcmp(arg, "--prefix=")) {
|
||||
state.base_dir = arg+9;
|
||||
state.base_dir_len = strlen(state.base_dir);
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(arg, "--stage=", 8)) {
|
||||
if (!prefixcmp(arg, "--stage=")) {
|
||||
if (!strcmp(arg + 8, "all")) {
|
||||
to_tempfile = 1;
|
||||
checkout_stage = CHECKOUT_ALL;
|
||||
|
@ -64,7 +64,7 @@ static int get_value(const char* key_, const char* regex_)
|
||||
int ret = -1;
|
||||
char *tl;
|
||||
char *global = NULL, *repo_config = NULL;
|
||||
const char *local;
|
||||
const char *system_wide = NULL, *local;
|
||||
|
||||
local = getenv(CONFIG_ENVIRONMENT);
|
||||
if (!local) {
|
||||
@ -74,6 +74,7 @@ static int get_value(const char* key_, const char* regex_)
|
||||
local = repo_config = xstrdup(git_path("config"));
|
||||
if (home)
|
||||
global = xstrdup(mkpath("%s/.gitconfig", home));
|
||||
system_wide = ETC_GITCONFIG;
|
||||
}
|
||||
|
||||
key = xstrdup(key_);
|
||||
@ -103,11 +104,15 @@ static int get_value(const char* key_, const char* regex_)
|
||||
}
|
||||
}
|
||||
|
||||
if (do_all && system_wide)
|
||||
git_config_from_file(show_config, system_wide);
|
||||
if (do_all && global)
|
||||
git_config_from_file(show_config, global);
|
||||
git_config_from_file(show_config, local);
|
||||
if (!do_all && !seen && global)
|
||||
git_config_from_file(show_config, global);
|
||||
if (!do_all && !seen && system_wide)
|
||||
git_config_from_file(show_config, system_wide);
|
||||
|
||||
free(key);
|
||||
if (regexp) {
|
||||
@ -147,7 +152,10 @@ int cmd_config(int argc, const char **argv, const char *prefix)
|
||||
} else {
|
||||
die("$HOME not set");
|
||||
}
|
||||
} else if (!strcmp(argv[1], "--rename-section")) {
|
||||
}
|
||||
else if (!strcmp(argv[1], "--system"))
|
||||
setenv("GIT_CONFIG", ETC_GITCONFIG, 1);
|
||||
else if (!strcmp(argv[1], "--rename-section")) {
|
||||
int ret;
|
||||
if (argc != 4)
|
||||
usage(git_config_set_usage);
|
||||
@ -159,7 +167,8 @@ int cmd_config(int argc, const char **argv, const char *prefix)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
} else
|
||||
}
|
||||
else
|
||||
break;
|
||||
argc--;
|
||||
argv++;
|
||||
|
@ -52,7 +52,7 @@ static int get_name(const char *path, const unsigned char *sha1, int flag, void
|
||||
* If --tags, then any tags are used.
|
||||
* Otherwise only annotated tags are used.
|
||||
*/
|
||||
if (!strncmp(path, "refs/tags/", 10)) {
|
||||
if (!prefixcmp(path, "refs/tags/")) {
|
||||
if (object->type == OBJ_TAG)
|
||||
prio = 2;
|
||||
else
|
||||
@ -254,12 +254,12 @@ int cmd_describe(int argc, const char **argv, const char *prefix)
|
||||
all = 1;
|
||||
else if (!strcmp(arg, "--tags"))
|
||||
tags = 1;
|
||||
else if (!strncmp(arg, "--abbrev=", 9)) {
|
||||
else if (!prefixcmp(arg, "--abbrev=")) {
|
||||
abbrev = strtoul(arg + 9, NULL, 10);
|
||||
if (abbrev != 0 && (abbrev < MINIMUM_ABBREV || 40 < abbrev))
|
||||
abbrev = DEFAULT_ABBREV;
|
||||
}
|
||||
else if (!strncmp(arg, "--candidates=", 13)) {
|
||||
else if (!prefixcmp(arg, "--candidates=")) {
|
||||
max_candidates = strtoul(arg + 13, NULL, 10);
|
||||
if (max_candidates < 1)
|
||||
max_candidates = 1;
|
||||
|
@ -162,7 +162,8 @@ 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++)
|
||||
hashcpy((unsigned char*)parent + i, ent[ents - 1 - i].item->sha1);
|
||||
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;
|
||||
@ -232,6 +233,8 @@ int cmd_diff(int argc, const char **argv, const char *prefix)
|
||||
break;
|
||||
else if (!strcmp(arg, "--cached")) {
|
||||
add_head(&rev);
|
||||
if (!rev.pending.nr)
|
||||
die("No HEAD commit to compare with (yet)");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -81,7 +81,7 @@ static int handle_line(char *line)
|
||||
if (len < 43 || line[40] != '\t')
|
||||
return 1;
|
||||
|
||||
if (!strncmp(line + 41, "not-for-merge", 13))
|
||||
if (!prefixcmp(line + 41, "not-for-merge"))
|
||||
return 0;
|
||||
|
||||
if (line[41] != '\t')
|
||||
@ -119,15 +119,15 @@ static int handle_line(char *line)
|
||||
if (pulling_head) {
|
||||
origin = xstrdup(src);
|
||||
src_data->head_status |= 1;
|
||||
} else if (!strncmp(line, "branch ", 7)) {
|
||||
} else if (!prefixcmp(line, "branch ")) {
|
||||
origin = xstrdup(line + 7);
|
||||
append_to_list(&src_data->branch, origin, NULL);
|
||||
src_data->head_status |= 2;
|
||||
} else if (!strncmp(line, "tag ", 4)) {
|
||||
} else if (!prefixcmp(line, "tag ")) {
|
||||
origin = line;
|
||||
append_to_list(&src_data->tag, xstrdup(origin + 4), NULL);
|
||||
src_data->head_status |= 2;
|
||||
} else if (!strncmp(line, "remote branch ", 14)) {
|
||||
} else if (!prefixcmp(line, "remote branch ")) {
|
||||
origin = xstrdup(line + 14);
|
||||
append_to_list(&src_data->r_branch, origin, NULL);
|
||||
src_data->head_status |= 2;
|
||||
@ -280,7 +280,7 @@ int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix)
|
||||
current_branch = resolve_ref("HEAD", head_sha1, 1, NULL);
|
||||
if (!current_branch)
|
||||
die("No current branch");
|
||||
if (!strncmp(current_branch, "refs/heads/", 11))
|
||||
if (!prefixcmp(current_branch, "refs/heads/"))
|
||||
current_branch += 11;
|
||||
|
||||
while (fgets(line, sizeof(line), in)) {
|
||||
|
@ -814,7 +814,7 @@ int cmd_for_each_ref(int ac, const char **av, char *prefix)
|
||||
i++;
|
||||
break;
|
||||
}
|
||||
if (!strncmp(arg, "--format=", 9)) {
|
||||
if (!prefixcmp(arg, "--format=")) {
|
||||
if (format)
|
||||
die("more than one --format?");
|
||||
format = arg + 9;
|
||||
@ -844,7 +844,7 @@ int cmd_for_each_ref(int ac, const char **av, char *prefix)
|
||||
quote_style = QUOTE_TCL;
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(arg, "--count=", 8)) {
|
||||
if (!prefixcmp(arg, "--count=")) {
|
||||
if (maxcount)
|
||||
die("more than one --count?");
|
||||
maxcount = atoi(arg + 8);
|
||||
@ -852,7 +852,7 @@ int cmd_for_each_ref(int ac, const char **av, char *prefix)
|
||||
die("The number %s did not parse", arg);
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(arg, "--sort=", 7)) {
|
||||
if (!prefixcmp(arg, "--sort=")) {
|
||||
struct ref_sort *s = xcalloc(1, sizeof(*s));
|
||||
int len;
|
||||
|
||||
|
@ -546,7 +546,7 @@ static int fsck_head_link(void)
|
||||
|
||||
if (!head_points_at || !(flag & REF_ISSYMREF))
|
||||
return error("HEAD is not a symbolic ref");
|
||||
if (strncmp(head_points_at, "refs/heads/", 11))
|
||||
if (prefixcmp(head_points_at, "refs/heads/"))
|
||||
return error("HEAD points to something strange (%s)",
|
||||
head_points_at);
|
||||
if (is_null_sha1(sha1))
|
||||
|
@ -527,9 +527,9 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
|
||||
opt.word_regexp = 1;
|
||||
continue;
|
||||
}
|
||||
if (!strncmp("-A", arg, 2) ||
|
||||
!strncmp("-B", arg, 2) ||
|
||||
!strncmp("-C", arg, 2) ||
|
||||
if (!prefixcmp(arg, "-A") ||
|
||||
!prefixcmp(arg, "-B") ||
|
||||
!prefixcmp(arg, "-C") ||
|
||||
(arg[0] == '-' && '1' <= arg[1] && arg[1] <= '9')) {
|
||||
unsigned num;
|
||||
const char *scan;
|
||||
|
@ -283,11 +283,11 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
|
||||
|
||||
for (i = 1; i < argc; i++, argv++) {
|
||||
const char *arg = argv[1];
|
||||
if (!strncmp(arg, "--template=", 11))
|
||||
if (!prefixcmp(arg, "--template="))
|
||||
template_dir = arg+11;
|
||||
else if (!strcmp(arg, "--shared"))
|
||||
shared_repository = PERM_GROUP;
|
||||
else if (!strncmp(arg, "--shared=", 9))
|
||||
else if (!prefixcmp(arg, "--shared="))
|
||||
shared_repository = git_config_perm("arg", arg+9);
|
||||
else
|
||||
usage(init_db_usage);
|
||||
|
@ -32,7 +32,7 @@ static void cmd_log_init(int argc, const char **argv, const char *prefix,
|
||||
rev->always_show_header = 0;
|
||||
for (i = 1; i < argc; i++) {
|
||||
const char *arg = argv[i];
|
||||
if (!strncmp(arg, "--encoding=", 11)) {
|
||||
if (!prefixcmp(arg, "--encoding=")) {
|
||||
arg += 11;
|
||||
if (strcmp(arg, "none"))
|
||||
git_log_output_encoding = strdup(arg);
|
||||
@ -224,6 +224,9 @@ int cmd_log(int argc, const char **argv, const char *prefix)
|
||||
return cmd_log_walk(&rev);
|
||||
}
|
||||
|
||||
/* format-patch */
|
||||
#define FORMAT_PATCH_NAME_MAX 64
|
||||
|
||||
static int istitlechar(char c)
|
||||
{
|
||||
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
|
||||
@ -264,15 +267,18 @@ static int git_format_config(const char *var, const char *value)
|
||||
static FILE *realstdout = NULL;
|
||||
static const char *output_directory = NULL;
|
||||
|
||||
static void reopen_stdout(struct commit *commit, int nr, int keep_subject)
|
||||
static int reopen_stdout(struct commit *commit, int nr, int keep_subject)
|
||||
{
|
||||
char filename[1024];
|
||||
char filename[PATH_MAX];
|
||||
char *sol;
|
||||
int len = 0;
|
||||
int suffix_len = strlen(fmt_patch_suffix) + 10; /* ., NUL and slop */
|
||||
int suffix_len = strlen(fmt_patch_suffix) + 1;
|
||||
|
||||
if (output_directory) {
|
||||
strlcpy(filename, output_directory, 1000);
|
||||
if (strlen(output_directory) >=
|
||||
sizeof(filename) - FORMAT_PATCH_NAME_MAX - suffix_len)
|
||||
return error("name of output directory is too long");
|
||||
strlcpy(filename, output_directory, sizeof(filename) - suffix_len);
|
||||
len = strlen(filename);
|
||||
if (filename[len - 1] != '/')
|
||||
filename[len++] = '/';
|
||||
@ -287,7 +293,7 @@ static void reopen_stdout(struct commit *commit, int nr, int keep_subject)
|
||||
|
||||
sol += 2;
|
||||
/* strip [PATCH] or [PATCH blabla] */
|
||||
if (!keep_subject && !strncmp(sol, "[PATCH", 6)) {
|
||||
if (!keep_subject && !prefixcmp(sol, "[PATCH")) {
|
||||
char *eos = strchr(sol + 6, ']');
|
||||
if (eos) {
|
||||
while (isspace(*eos))
|
||||
@ -297,7 +303,8 @@ static void reopen_stdout(struct commit *commit, int nr, int keep_subject)
|
||||
}
|
||||
|
||||
for (j = 0;
|
||||
len < sizeof(filename) - suffix_len &&
|
||||
j < FORMAT_PATCH_NAME_MAX - suffix_len - 5 &&
|
||||
len < sizeof(filename) - suffix_len &&
|
||||
sol[j] && sol[j] != '\n';
|
||||
j++) {
|
||||
if (istitlechar(sol[j])) {
|
||||
@ -314,10 +321,16 @@ static void reopen_stdout(struct commit *commit, int nr, int keep_subject)
|
||||
}
|
||||
while (filename[len - 1] == '.' || filename[len - 1] == '-')
|
||||
len--;
|
||||
filename[len] = 0;
|
||||
}
|
||||
if (len + suffix_len >= sizeof(filename))
|
||||
return error("Patch pathname too long");
|
||||
strcpy(filename + len, fmt_patch_suffix);
|
||||
fprintf(realstdout, "%s\n", filename);
|
||||
freopen(filename, "w", stdout);
|
||||
if (freopen(filename, "w", stdout) == NULL)
|
||||
return error("Cannot open patch file %s",filename);
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
static int get_patch_id(struct commit *commit, struct diff_options *options,
|
||||
@ -435,7 +448,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
|
||||
else if (!strcmp(argv[i], "-n") ||
|
||||
!strcmp(argv[i], "--numbered"))
|
||||
numbered = 1;
|
||||
else if (!strncmp(argv[i], "--start-number=", 15))
|
||||
else if (!prefixcmp(argv[i], "--start-number="))
|
||||
start_number = strtol(argv[i] + 15, NULL, 10);
|
||||
else if (!strcmp(argv[i], "--start-number")) {
|
||||
i++;
|
||||
@ -471,13 +484,13 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
|
||||
}
|
||||
else if (!strcmp(argv[i], "--attach"))
|
||||
rev.mime_boundary = git_version_string;
|
||||
else if (!strncmp(argv[i], "--attach=", 9))
|
||||
else if (!prefixcmp(argv[i], "--attach="))
|
||||
rev.mime_boundary = argv[i] + 9;
|
||||
else if (!strcmp(argv[i], "--ignore-if-in-upstream"))
|
||||
ignore_if_in_upstream = 1;
|
||||
else if (!strcmp(argv[i], "--thread"))
|
||||
thread = 1;
|
||||
else if (!strncmp(argv[i], "--in-reply-to=", 14))
|
||||
else if (!prefixcmp(argv[i], "--in-reply-to="))
|
||||
in_reply_to = argv[i] + 14;
|
||||
else if (!strcmp(argv[i], "--in-reply-to")) {
|
||||
i++;
|
||||
@ -485,7 +498,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
|
||||
die("Need a Message-Id for --in-reply-to");
|
||||
in_reply_to = argv[i];
|
||||
}
|
||||
else if (!strncmp(argv[i], "--suffix=", 9))
|
||||
else if (!prefixcmp(argv[i], "--suffix="))
|
||||
fmt_patch_suffix = argv[i] + 9;
|
||||
else
|
||||
argv[j++] = argv[i];
|
||||
@ -573,7 +586,8 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
|
||||
rev.message_id = message_id;
|
||||
}
|
||||
if (!use_stdout)
|
||||
reopen_stdout(commit, rev.nr, keep_subject);
|
||||
if (reopen_stdout(commit, rev.nr, keep_subject))
|
||||
die("Failed to create output files");
|
||||
shown = log_tree_commit(&rev, commit);
|
||||
free(commit->buffer);
|
||||
commit->buffer = NULL;
|
||||
|
@ -406,7 +406,7 @@ int cmd_ls_files(int argc, const char **argv, const char *prefix)
|
||||
add_exclude(argv[++i], "", 0, &dir.exclude_list[EXC_CMDL]);
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(arg, "--exclude=", 10)) {
|
||||
if (!prefixcmp(arg, "--exclude=")) {
|
||||
exc_given = 1;
|
||||
add_exclude(arg+10, "", 0, &dir.exclude_list[EXC_CMDL]);
|
||||
continue;
|
||||
@ -416,12 +416,12 @@ int cmd_ls_files(int argc, const char **argv, const char *prefix)
|
||||
add_excludes_from_file(&dir, argv[++i]);
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(arg, "--exclude-from=", 15)) {
|
||||
if (!prefixcmp(arg, "--exclude-from=")) {
|
||||
exc_given = 1;
|
||||
add_excludes_from_file(&dir, arg+15);
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(arg, "--exclude-per-directory=", 24)) {
|
||||
if (!prefixcmp(arg, "--exclude-per-directory=")) {
|
||||
exc_given = 1;
|
||||
dir.exclude_per_dir = arg + 24;
|
||||
continue;
|
||||
@ -434,7 +434,7 @@ int cmd_ls_files(int argc, const char **argv, const char *prefix)
|
||||
error_unmatch = 1;
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(arg, "--abbrev=", 9)) {
|
||||
if (!prefixcmp(arg, "--abbrev=")) {
|
||||
abbrev = strtoul(arg+9, NULL, 10);
|
||||
if (abbrev && abbrev < MINIMUM_ABBREV)
|
||||
abbrev = MINIMUM_ABBREV;
|
||||
|
@ -118,7 +118,7 @@ int cmd_ls_tree(int argc, const char **argv, const char *prefix)
|
||||
chomp_prefix = 0;
|
||||
break;
|
||||
}
|
||||
if (!strncmp(argv[1]+2, "abbrev=",7)) {
|
||||
if (!prefixcmp(argv[1]+2, "abbrev=")) {
|
||||
abbrev = strtoul(argv[1]+9, NULL, 10);
|
||||
if (abbrev && abbrev < MINIMUM_ABBREV)
|
||||
abbrev = MINIMUM_ABBREV;
|
||||
|
@ -811,7 +811,7 @@ int cmd_mailinfo(int argc, const char **argv, const char *prefix)
|
||||
metainfo_charset = def_charset;
|
||||
else if (!strcmp(argv[1], "-n"))
|
||||
metainfo_charset = NULL;
|
||||
else if (!strncmp(argv[1], "--encoding=", 11))
|
||||
else if (!prefixcmp(argv[1], "--encoding="))
|
||||
metainfo_charset = argv[1] + 11;
|
||||
else
|
||||
usage(mailinfo_usage);
|
||||
|
@ -57,13 +57,17 @@ copy_data:
|
||||
parents;
|
||||
parents = parents->next, parent_number++) {
|
||||
if (parent_number > 1) {
|
||||
char *new_name = xmalloc(strlen(tip_name)+8);
|
||||
int len = strlen(tip_name);
|
||||
char *new_name = xmalloc(len + 8);
|
||||
|
||||
if (len > 2 && !strcmp(tip_name + len - 2, "^0"))
|
||||
len -= 2;
|
||||
if (generation > 0)
|
||||
sprintf(new_name, "%s~%d^%d", tip_name,
|
||||
sprintf(new_name, "%.*s~%d^%d", len, tip_name,
|
||||
generation, parent_number);
|
||||
else
|
||||
sprintf(new_name, "%s^%d", tip_name, parent_number);
|
||||
sprintf(new_name, "%.*s^%d", len, tip_name,
|
||||
parent_number);
|
||||
|
||||
name_rev(parents->item, new_name,
|
||||
merge_traversals + 1 , 0, 0);
|
||||
@ -85,7 +89,7 @@ static int name_ref(const char *path, const unsigned char *sha1, int flags, void
|
||||
struct name_ref_data *data = cb_data;
|
||||
int deref = 0;
|
||||
|
||||
if (data->tags_only && strncmp(path, "refs/tags/", 10))
|
||||
if (data->tags_only && prefixcmp(path, "refs/tags/"))
|
||||
return 0;
|
||||
|
||||
if (data->ref_filter && fnmatch(data->ref_filter, path, 0))
|
||||
@ -101,9 +105,9 @@ static int name_ref(const char *path, const unsigned char *sha1, int flags, void
|
||||
if (o && o->type == OBJ_COMMIT) {
|
||||
struct commit *commit = (struct commit *)o;
|
||||
|
||||
if (!strncmp(path, "refs/heads/", 11))
|
||||
if (!prefixcmp(path, "refs/heads/"))
|
||||
path = path + 11;
|
||||
else if (!strncmp(path, "refs/", 5))
|
||||
else if (!prefixcmp(path, "refs/"))
|
||||
path = path + 5;
|
||||
|
||||
name_rev(commit, xstrdup(path), 0, 0, deref);
|
||||
@ -127,10 +131,15 @@ static const char* get_rev_name(struct object *o)
|
||||
|
||||
if (!n->generation)
|
||||
return n->tip_name;
|
||||
else {
|
||||
int len = strlen(n->tip_name);
|
||||
if (len > 2 && !strcmp(n->tip_name + len - 2, "^0"))
|
||||
len -= 2;
|
||||
snprintf(buffer, sizeof(buffer), "%.*s~%d", len, n->tip_name,
|
||||
n->generation);
|
||||
|
||||
snprintf(buffer, sizeof(buffer), "%s~%d", n->tip_name, n->generation);
|
||||
|
||||
return buffer;
|
||||
return buffer;
|
||||
}
|
||||
}
|
||||
|
||||
int cmd_name_rev(int argc, const char **argv, const char *prefix)
|
||||
@ -156,7 +165,7 @@ int cmd_name_rev(int argc, const char **argv, const char *prefix)
|
||||
} else if (!strcmp(*argv, "--tags")) {
|
||||
data.tags_only = 1;
|
||||
continue;
|
||||
} else if (!strncmp(*argv, "--refs=", 7)) {
|
||||
} else if (!prefixcmp(*argv, "--refs=")) {
|
||||
data.ref_filter = *argv + 7;
|
||||
continue;
|
||||
} else if (!strcmp(*argv, "--all")) {
|
||||
|
@ -1551,9 +1551,12 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
|
||||
int use_internal_rev_list = 0;
|
||||
int thin = 0;
|
||||
int i;
|
||||
const char *rp_av[64];
|
||||
const char **rp_av;
|
||||
int rp_ac_alloc = 64;
|
||||
int rp_ac;
|
||||
|
||||
rp_av = xcalloc(rp_ac_alloc, sizeof(*rp_av));
|
||||
|
||||
rp_av[0] = "pack-objects";
|
||||
rp_av[1] = "--objects"; /* --thin will make it --objects-edge */
|
||||
rp_ac = 2;
|
||||
@ -1579,14 +1582,14 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
|
||||
incremental = 1;
|
||||
continue;
|
||||
}
|
||||
if (!strncmp("--window=", arg, 9)) {
|
||||
if (!prefixcmp(arg, "--window=")) {
|
||||
char *end;
|
||||
window = strtoul(arg+9, &end, 0);
|
||||
if (!arg[9] || *end)
|
||||
usage(pack_usage);
|
||||
continue;
|
||||
}
|
||||
if (!strncmp("--depth=", arg, 8)) {
|
||||
if (!prefixcmp(arg, "--depth=")) {
|
||||
char *end;
|
||||
depth = strtoul(arg+8, &end, 0);
|
||||
if (!arg[8] || *end)
|
||||
@ -1622,12 +1625,15 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
|
||||
continue;
|
||||
}
|
||||
if (!strcmp("--unpacked", arg) ||
|
||||
!strncmp("--unpacked=", arg, 11) ||
|
||||
!prefixcmp(arg, "--unpacked=") ||
|
||||
!strcmp("--reflog", arg) ||
|
||||
!strcmp("--all", arg)) {
|
||||
use_internal_rev_list = 1;
|
||||
if (ARRAY_SIZE(rp_av) - 1 <= rp_ac)
|
||||
die("too many internal rev-list options");
|
||||
if (rp_ac >= rp_ac_alloc - 1) {
|
||||
rp_ac_alloc = alloc_nr(rp_ac_alloc);
|
||||
rp_av = xrealloc(rp_av,
|
||||
rp_ac_alloc * sizeof(*rp_av));
|
||||
}
|
||||
rp_av[rp_ac++] = arg;
|
||||
continue;
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ static int handle_one_ref(const char *path, const unsigned char *sha1,
|
||||
/* Do not pack the symbolic refs */
|
||||
if ((flags & REF_ISSYMREF))
|
||||
return 0;
|
||||
is_tag_ref = !strncmp(path, "refs/tags/", 10);
|
||||
is_tag_ref = !prefixcmp(path, "refs/tags/");
|
||||
|
||||
/* ALWAYS pack refs that were already packed or are tags */
|
||||
if (!cb->all && !is_tag_ref && !(flags & REF_ISPACKED))
|
||||
|
@ -32,7 +32,7 @@ static int expand_one_ref(const char *ref, const unsigned char *sha1, int flag,
|
||||
/* Ignore the "refs/" at the beginning of the refname */
|
||||
ref += 5;
|
||||
|
||||
if (!strncmp(ref, "tags/", 5))
|
||||
if (!prefixcmp(ref, "tags/"))
|
||||
add_refspec(xstrdup(ref));
|
||||
return 0;
|
||||
}
|
||||
@ -149,10 +149,10 @@ static int get_remotes_uri(const char *repo, const char *uri[MAX_URI])
|
||||
int is_refspec;
|
||||
char *s, *p;
|
||||
|
||||
if (!strncmp("URL:", buffer, 4)) {
|
||||
if (!prefixcmp(buffer, "URL:")) {
|
||||
is_refspec = 0;
|
||||
s = buffer + 4;
|
||||
} else if (!strncmp("Push:", buffer, 5)) {
|
||||
} else if (!prefixcmp(buffer, "Push:")) {
|
||||
is_refspec = 1;
|
||||
s = buffer + 5;
|
||||
} else
|
||||
@ -195,7 +195,7 @@ static int config_get_receivepack;
|
||||
|
||||
static int get_remote_config(const char* key, const char* value)
|
||||
{
|
||||
if (!strncmp(key, "remote.", 7) &&
|
||||
if (!prefixcmp(key, "remote.") &&
|
||||
!strncmp(key + 7, config_repo, config_repo_len)) {
|
||||
if (!strcmp(key + 7 + config_repo_len, ".url")) {
|
||||
if (config_current_uri < MAX_URI)
|
||||
@ -324,8 +324,8 @@ static int do_push(const char *repo)
|
||||
const char **dest_refspec = refspec;
|
||||
const char *dest = uri[i];
|
||||
const char *sender = "git-send-pack";
|
||||
if (!strncmp(dest, "http://", 7) ||
|
||||
!strncmp(dest, "https://", 8))
|
||||
if (!prefixcmp(dest, "http://") ||
|
||||
!prefixcmp(dest, "https://"))
|
||||
sender = "git-http-push";
|
||||
else if (thin)
|
||||
argv[dest_argc++] = "--thin";
|
||||
@ -373,7 +373,7 @@ int cmd_push(int argc, const char **argv, const char *prefix)
|
||||
verbose=1;
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(arg, "--repo=", 7)) {
|
||||
if (!prefixcmp(arg, "--repo=")) {
|
||||
repo = arg+7;
|
||||
continue;
|
||||
}
|
||||
@ -397,11 +397,11 @@ int cmd_push(int argc, const char **argv, const char *prefix)
|
||||
thin = 0;
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(arg, "--receive-pack=", 15)) {
|
||||
if (!prefixcmp(arg, "--receive-pack=")) {
|
||||
receivepack = arg;
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(arg, "--exec=", 7)) {
|
||||
if (!prefixcmp(arg, "--exec=")) {
|
||||
receivepack = arg;
|
||||
continue;
|
||||
}
|
||||
|
@ -133,7 +133,7 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix)
|
||||
* entries and put the entries from the tree under the
|
||||
* given subdirectory.
|
||||
*/
|
||||
if (!strncmp(arg, "--prefix=", 9)) {
|
||||
if (!prefixcmp(arg, "--prefix=")) {
|
||||
if (stage || opts.merge || opts.prefix)
|
||||
usage(read_tree_usage);
|
||||
opts.prefix = arg + 9;
|
||||
@ -179,7 +179,7 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!strncmp(arg, "--exclude-per-directory=", 24)) {
|
||||
if (!prefixcmp(arg, "--exclude-per-directory=")) {
|
||||
struct dir_struct *dir;
|
||||
|
||||
if (opts.dir)
|
||||
|
@ -321,9 +321,9 @@ static int cmd_reflog_expire(int argc, const char **argv, const char *prefix)
|
||||
const char *arg = argv[i];
|
||||
if (!strcmp(arg, "--dry-run") || !strcmp(arg, "-n"))
|
||||
cb.dry_run = 1;
|
||||
else if (!strncmp(arg, "--expire=", 9))
|
||||
else if (!prefixcmp(arg, "--expire="))
|
||||
cb.expire_total = approxidate(arg + 9);
|
||||
else if (!strncmp(arg, "--expire-unreachable=", 21))
|
||||
else if (!prefixcmp(arg, "--expire-unreachable="))
|
||||
cb.expire_unreachable = approxidate(arg + 21);
|
||||
else if (!strcmp(arg, "--stale-fix"))
|
||||
cb.stalefix = 1;
|
||||
|
@ -105,11 +105,11 @@ static int handle_file(const char *path,
|
||||
SHA1_Init(&ctx);
|
||||
|
||||
while (fgets(buf, sizeof(buf), f)) {
|
||||
if (!strncmp("<<<<<<< ", buf, 8))
|
||||
if (!prefixcmp(buf, "<<<<<<< "))
|
||||
hunk = 1;
|
||||
else if (!strncmp("=======", buf, 7))
|
||||
else if (!prefixcmp(buf, "======="))
|
||||
hunk = 2;
|
||||
else if (!strncmp(">>>>>>> ", buf, 8)) {
|
||||
else if (!prefixcmp(buf, ">>>>>>> ")) {
|
||||
hunk_no++;
|
||||
hunk = 0;
|
||||
if (memcmp(one->ptr, two->ptr, one->nr < two->nr ?
|
||||
@ -154,13 +154,17 @@ static int find_conflict(struct path_list *conflict)
|
||||
return error("Could not read index");
|
||||
for (i = 0; i + 2 < active_nr; i++) {
|
||||
struct cache_entry *e1 = active_cache[i];
|
||||
struct cache_entry *e2 = active_cache[i + 1];
|
||||
struct cache_entry *e3 = active_cache[i + 2];
|
||||
if (ce_stage(e1) == 1 && ce_stage(e2) == 2 &&
|
||||
ce_stage(e3) == 3 && ce_same_name(e1, e2) &&
|
||||
ce_same_name(e1, e3)) {
|
||||
struct cache_entry *e2 = active_cache[i+1];
|
||||
struct cache_entry *e3 = active_cache[i+2];
|
||||
if (ce_stage(e1) == 1 &&
|
||||
ce_stage(e2) == 2 &&
|
||||
ce_stage(e3) == 3 &&
|
||||
ce_same_name(e1, e2) && ce_same_name(e1, e3) &&
|
||||
S_ISREG(ntohl(e1->ce_mode)) &&
|
||||
S_ISREG(ntohl(e2->ce_mode)) &&
|
||||
S_ISREG(ntohl(e3->ce_mode))) {
|
||||
path_list_insert((const char *)e1->name, conflict);
|
||||
i += 3;
|
||||
i += 2;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
@ -233,7 +233,7 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(arg,"-n",2)) {
|
||||
if (!prefixcmp(arg, "-n")) {
|
||||
if ((filter & DO_FLAGS) && (filter & DO_REVS))
|
||||
show(arg);
|
||||
continue;
|
||||
@ -274,7 +274,7 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(arg, "--short") ||
|
||||
!strncmp(arg, "--short=", 8)) {
|
||||
!prefixcmp(arg, "--short=")) {
|
||||
filter &= ~(DO_FLAGS|DO_NOREV);
|
||||
verify = 1;
|
||||
abbrev = DEFAULT_ABBREV;
|
||||
@ -352,19 +352,19 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
|
||||
: "false");
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(arg, "--since=", 8)) {
|
||||
if (!prefixcmp(arg, "--since=")) {
|
||||
show_datestring("--max-age=", arg+8);
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(arg, "--after=", 8)) {
|
||||
if (!prefixcmp(arg, "--after=")) {
|
||||
show_datestring("--max-age=", arg+8);
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(arg, "--before=", 9)) {
|
||||
if (!prefixcmp(arg, "--before=")) {
|
||||
show_datestring("--min-age=", arg+9);
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(arg, "--until=", 8)) {
|
||||
if (!prefixcmp(arg, "--until=")) {
|
||||
show_datestring("--min-age=", arg+8);
|
||||
continue;
|
||||
}
|
||||
|
@ -124,7 +124,7 @@ static void insert_author_oneline(struct path_list *list,
|
||||
else
|
||||
free(buffer);
|
||||
|
||||
if (!strncmp(oneline, "[PATCH", 6)) {
|
||||
if (!prefixcmp(oneline, "[PATCH")) {
|
||||
char *eob = strchr(oneline, ']');
|
||||
|
||||
if (eob) {
|
||||
@ -179,7 +179,7 @@ static void read_from_stdin(struct path_list *list)
|
||||
while (fgets(buffer, sizeof(buffer), stdin) != NULL) {
|
||||
char *bob;
|
||||
if ((buffer[0] == 'A' || buffer[0] == 'a') &&
|
||||
!strncmp(buffer + 1, "uthor: ", 7) &&
|
||||
!prefixcmp(buffer + 1, "uthor: ") &&
|
||||
(bob = strchr(buffer + 7, '<')) != NULL) {
|
||||
char buffer2[1024], offset = 0;
|
||||
|
||||
@ -230,7 +230,7 @@ static void get_from_rev(struct rev_info *rev, struct path_list *list)
|
||||
else
|
||||
eol++;
|
||||
|
||||
if (!strncmp(buffer, "author ", 7)) {
|
||||
if (!prefixcmp(buffer, "author ")) {
|
||||
char *bracket = strchr(buffer, '<');
|
||||
|
||||
if (bracket == NULL || bracket > eol)
|
||||
|
@ -266,7 +266,7 @@ static void show_one_commit(struct commit *commit, int no_name)
|
||||
pretty, sizeof(pretty), 0, NULL, NULL, 0);
|
||||
else
|
||||
strcpy(pretty, "(unavailable)");
|
||||
if (!strncmp(pretty, "[PATCH] ", 8))
|
||||
if (!prefixcmp(pretty, "[PATCH] "))
|
||||
cp = pretty + 8;
|
||||
else
|
||||
cp = pretty;
|
||||
@ -378,7 +378,7 @@ static int append_head_ref(const char *refname, const unsigned char *sha1, int f
|
||||
{
|
||||
unsigned char tmp[20];
|
||||
int ofs = 11;
|
||||
if (strncmp(refname, "refs/heads/", ofs))
|
||||
if (prefixcmp(refname, "refs/heads/"))
|
||||
return 0;
|
||||
/* If both heads/foo and tags/foo exists, get_sha1 would
|
||||
* get confused.
|
||||
@ -392,7 +392,7 @@ static int append_remote_ref(const char *refname, const unsigned char *sha1, int
|
||||
{
|
||||
unsigned char tmp[20];
|
||||
int ofs = 13;
|
||||
if (strncmp(refname, "refs/remotes/", ofs))
|
||||
if (prefixcmp(refname, "refs/remotes/"))
|
||||
return 0;
|
||||
/* If both heads/foo and tags/foo exists, get_sha1 would
|
||||
* get confused.
|
||||
@ -404,7 +404,7 @@ static int append_remote_ref(const char *refname, const unsigned char *sha1, int
|
||||
|
||||
static int append_tag_ref(const char *refname, const unsigned char *sha1, int flag, void *cb_data)
|
||||
{
|
||||
if (strncmp(refname, "refs/tags/", 10))
|
||||
if (prefixcmp(refname, "refs/tags/"))
|
||||
return 0;
|
||||
return append_ref(refname + 5, sha1, 0);
|
||||
}
|
||||
@ -435,9 +435,9 @@ static int append_matching_ref(const char *refname, const unsigned char *sha1, i
|
||||
return 0;
|
||||
if (fnmatch(match_ref_pattern, tail, 0))
|
||||
return 0;
|
||||
if (!strncmp("refs/heads/", refname, 11))
|
||||
if (!prefixcmp(refname, "refs/heads/"))
|
||||
return append_head_ref(refname, sha1, flag, cb_data);
|
||||
if (!strncmp("refs/tags/", refname, 10))
|
||||
if (!prefixcmp(refname, "refs/tags/"))
|
||||
return append_tag_ref(refname, sha1, flag, cb_data);
|
||||
return append_ref(refname, sha1, 0);
|
||||
}
|
||||
@ -462,11 +462,11 @@ static int rev_is_head(char *head, int headlen, char *name,
|
||||
if ((!head[0]) ||
|
||||
(head_sha1 && sha1 && hashcmp(head_sha1, sha1)))
|
||||
return 0;
|
||||
if (!strncmp(head, "refs/heads/", 11))
|
||||
if (!prefixcmp(head, "refs/heads/"))
|
||||
head += 11;
|
||||
if (!strncmp(name, "refs/heads/", 11))
|
||||
if (!prefixcmp(name, "refs/heads/"))
|
||||
name += 11;
|
||||
else if (!strncmp(name, "heads/", 6))
|
||||
else if (!prefixcmp(name, "heads/"))
|
||||
name += 6;
|
||||
return !strcmp(head, name);
|
||||
}
|
||||
@ -635,7 +635,7 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
|
||||
with_current_branch = 1;
|
||||
else if (!strcmp(arg, "--sha1-name"))
|
||||
sha1_name = 1;
|
||||
else if (!strncmp(arg, "--more=", 7))
|
||||
else if (!prefixcmp(arg, "--more="))
|
||||
extra = atoi(arg + 7);
|
||||
else if (!strcmp(arg, "--merge-base"))
|
||||
merge_base = 1;
|
||||
@ -652,9 +652,9 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
|
||||
else if (!strcmp(arg, "--reflog") || !strcmp(arg, "-g")) {
|
||||
reflog = DEFAULT_REFLOG;
|
||||
}
|
||||
else if (!strncmp(arg, "--reflog=", 9))
|
||||
else if (!prefixcmp(arg, "--reflog="))
|
||||
parse_reflog_param(arg + 9, &reflog, &reflog_base);
|
||||
else if (!strncmp(arg, "-g=", 3))
|
||||
else if (!prefixcmp(arg, "-g="))
|
||||
parse_reflog_param(arg + 3, &reflog, &reflog_base);
|
||||
else
|
||||
usage(show_branch_usage);
|
||||
|
@ -28,8 +28,8 @@ static int show_ref(const char *refname, const unsigned char *sha1, int flag, vo
|
||||
if (tags_only || heads_only) {
|
||||
int match;
|
||||
|
||||
match = heads_only && !strncmp(refname, "refs/heads/", 11);
|
||||
match |= tags_only && !strncmp(refname, "refs/tags/", 10);
|
||||
match = heads_only && !prefixcmp(refname, "refs/heads/");
|
||||
match |= tags_only && !prefixcmp(refname, "refs/tags/");
|
||||
if (!match)
|
||||
return 0;
|
||||
}
|
||||
@ -178,8 +178,8 @@ int cmd_show_ref(int argc, const char **argv, const char *prefix)
|
||||
hash_only = 1;
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(arg, "--hash=", 7) ||
|
||||
(!strncmp(arg, "--abbrev", 8) &&
|
||||
if (!prefixcmp(arg, "--hash=") ||
|
||||
(!prefixcmp(arg, "--abbrev") &&
|
||||
(arg[8] == '=' || arg[8] == '\0'))) {
|
||||
if (arg[2] != 'h' && !arg[8])
|
||||
/* --abbrev only */
|
||||
@ -215,16 +215,18 @@ int cmd_show_ref(int argc, const char **argv, const char *prefix)
|
||||
}
|
||||
if (!strcmp(arg, "--exclude-existing"))
|
||||
return exclude_existing(NULL);
|
||||
if (!strncmp(arg, "--exclude-existing=", 19))
|
||||
if (!prefixcmp(arg, "--exclude-existing="))
|
||||
return exclude_existing(arg + 19);
|
||||
usage(show_ref_usage);
|
||||
}
|
||||
|
||||
if (verify) {
|
||||
unsigned char sha1[20];
|
||||
|
||||
if (!pattern)
|
||||
die("--verify requires a reference");
|
||||
while (*pattern) {
|
||||
if (!strncmp(*pattern, "refs/", 5) &&
|
||||
unsigned char sha1[20];
|
||||
|
||||
if (!prefixcmp(*pattern, "refs/") &&
|
||||
resolve_ref(*pattern, sha1, 1, NULL)) {
|
||||
if (!quiet)
|
||||
show_one(*pattern, sha1);
|
||||
|
@ -31,7 +31,7 @@ int cmd_tar_tree(int argc, const char **argv, const char *prefix)
|
||||
nargv[nargc++] = "git-archive";
|
||||
nargv[nargc++] = "--format=tar";
|
||||
|
||||
if (2 <= argc && !strncmp("--remote=", argv[1], 9)) {
|
||||
if (2 <= argc && !prefixcmp(argv[1], "--remote=")) {
|
||||
nargv[nargc++] = argv[1];
|
||||
argv++;
|
||||
argc--;
|
||||
|
@ -369,7 +369,7 @@ int cmd_unpack_objects(int argc, const char **argv, const char *prefix)
|
||||
recover = 1;
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(arg, "--pack_header=", 14)) {
|
||||
if (!prefixcmp(arg, "--pack_header=")) {
|
||||
struct pack_header *hdr;
|
||||
char *c;
|
||||
|
||||
|
@ -70,7 +70,7 @@ int cmd_write_tree(int argc, const char **argv, const char *unused_prefix)
|
||||
const char *arg = argv[1];
|
||||
if (!strcmp(arg, "--missing-ok"))
|
||||
missing_ok = 1;
|
||||
else if (!strncmp(arg, "--prefix=", 9))
|
||||
else if (!prefixcmp(arg, "--prefix="))
|
||||
prefix = arg + 9;
|
||||
else
|
||||
usage(write_tree_usage);
|
||||
|
5
cache.h
5
cache.h
@ -211,6 +211,7 @@ extern const char *apply_default_whitespace;
|
||||
extern int zlib_compression_level;
|
||||
extern size_t packed_git_window_size;
|
||||
extern size_t packed_git_limit;
|
||||
extern int auto_crlf;
|
||||
|
||||
#define GIT_REPO_VERSION 0
|
||||
extern int repository_format_version;
|
||||
@ -478,4 +479,8 @@ extern int nfvasprintf(char **str, const char *fmt, va_list va);
|
||||
extern void trace_printf(const char *format, ...);
|
||||
extern void trace_argv_printf(const char **argv, int count, const char *format, ...);
|
||||
|
||||
/* convert.c */
|
||||
extern int convert_to_git(const char *path, char **bufp, unsigned long *sizep);
|
||||
extern int convert_to_working_tree(const char *path, char **bufp, unsigned long *sizep);
|
||||
|
||||
#endif /* CACHE_H */
|
||||
|
@ -678,9 +678,25 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
|
||||
else {
|
||||
/* Used by diff-tree to read from the working tree */
|
||||
struct stat st;
|
||||
int fd;
|
||||
if (0 <= (fd = open(elem->path, O_RDONLY)) &&
|
||||
!fstat(fd, &st)) {
|
||||
int fd = -1;
|
||||
|
||||
if (lstat(elem->path, &st) < 0)
|
||||
goto deleted_file;
|
||||
|
||||
if (S_ISLNK(st.st_mode)) {
|
||||
int len = st.st_size;
|
||||
result_size = len;
|
||||
result = xmalloc(len + 1);
|
||||
if (result_size != readlink(elem->path, result, len)) {
|
||||
error("readlink(%s): %s", elem->path,
|
||||
strerror(errno));
|
||||
return;
|
||||
}
|
||||
result[len] = 0;
|
||||
elem->mode = canon_mode(st.st_mode);
|
||||
}
|
||||
else if (0 <= (fd = open(elem->path, O_RDONLY)) &&
|
||||
!fstat(fd, &st)) {
|
||||
int len = st.st_size;
|
||||
int sz = 0;
|
||||
|
||||
@ -698,11 +714,12 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
|
||||
result[len] = 0;
|
||||
}
|
||||
else {
|
||||
/* deleted file */
|
||||
deleted_file:
|
||||
result_size = 0;
|
||||
elem->mode = 0;
|
||||
result = xcalloc(1, 1);
|
||||
}
|
||||
|
||||
if (0 <= fd)
|
||||
close(fd);
|
||||
}
|
||||
|
10
compat/strtoumax.c
Normal file
10
compat/strtoumax.c
Normal file
@ -0,0 +1,10 @@
|
||||
#include "../git-compat-util.h"
|
||||
|
||||
uintmax_t gitstrtoumax (const char *nptr, char **endptr, int base)
|
||||
{
|
||||
#if defined(NO_STRTOULL)
|
||||
return strtoul(nptr, endptr, base);
|
||||
#else
|
||||
return strtoull(nptr, endptr, base);
|
||||
#endif
|
||||
}
|
11
config.c
11
config.c
@ -326,6 +326,15 @@ int git_default_config(const char *var, const char *value)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!strcmp(var, "core.autocrlf")) {
|
||||
if (value && !strcasecmp(value, "input")) {
|
||||
auto_crlf = -1;
|
||||
return 0;
|
||||
}
|
||||
auto_crlf = git_config_bool(var, value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!strcmp(var, "user.name")) {
|
||||
strlcpy(git_default_name, value, sizeof(git_default_name));
|
||||
return 0;
|
||||
@ -385,6 +394,8 @@ int git_config(config_fn_t fn)
|
||||
* config file otherwise. */
|
||||
filename = getenv(CONFIG_ENVIRONMENT);
|
||||
if (!filename) {
|
||||
if (!access(ETC_GITCONFIG, R_OK))
|
||||
ret += git_config_from_file(fn, ETC_GITCONFIG);
|
||||
home = getenv("HOME");
|
||||
filename = getenv(CONFIG_LOCAL_ENVIRONMENT);
|
||||
if (!filename)
|
||||
|
31
configure.ac
31
configure.ac
@ -114,13 +114,32 @@ AC_CHECK_LIB([expat], [XML_ParserCreate],
|
||||
[NO_EXPAT=YesPlease])
|
||||
AC_SUBST(NO_EXPAT)
|
||||
#
|
||||
# Define NEEDS_LIBICONV if linking with libc is not enough (Darwin).
|
||||
# Define NEEDS_LIBICONV if linking with libc is not enough (Darwin and
|
||||
# some Solaris installations).
|
||||
# Define NO_ICONV if neither libc nor libiconv support iconv.
|
||||
AC_CHECK_LIB([c], [iconv],
|
||||
[NEEDS_LIBICONV=],
|
||||
AC_CHECK_LIB([iconv], [iconv],
|
||||
[NEEDS_LIBICONV=YesPlease],
|
||||
[NO_ICONV=YesPlease]))
|
||||
AC_DEFUN([ICONVTEST_SRC], [
|
||||
#include <iconv.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
iconv_open("", "");
|
||||
return 0;
|
||||
}
|
||||
])
|
||||
AC_MSG_CHECKING([for iconv in -lc])
|
||||
AC_LINK_IFELSE(ICONVTEST_SRC,
|
||||
[AC_MSG_RESULT([yes])
|
||||
NEEDS_LIBICONV=],
|
||||
[AC_MSG_RESULT([no])
|
||||
old_LIBS="$LIBS"
|
||||
LIBS="$LIBS -liconv"
|
||||
AC_MSG_CHECKING([for iconv in -liconv])
|
||||
AC_LINK_IFELSE(ICONVTEST_SRC,
|
||||
[AC_MSG_RESULT([yes])
|
||||
NEEDS_LIBICONV=YesPlease],
|
||||
[AC_MSG_RESULT([no])
|
||||
NO_ICONV=YesPlease])
|
||||
LIBS="$old_LIBS"])
|
||||
AC_SUBST(NEEDS_LIBICONV)
|
||||
AC_SUBST(NO_ICONV)
|
||||
test -n "$NEEDS_LIBICONV" && LIBS="$LIBS -liconv"
|
||||
|
@ -96,7 +96,7 @@ int get_ack(int fd, unsigned char *result_sha1)
|
||||
line[--len] = 0;
|
||||
if (!strcmp(line, "NAK"))
|
||||
return 0;
|
||||
if (!strncmp(line, "ACK ", 4)) {
|
||||
if (!prefixcmp(line, "ACK ")) {
|
||||
if (!get_sha1_hex(line+4, result_sha1)) {
|
||||
if (strstr(line+45, "continue"))
|
||||
return 2;
|
||||
@ -196,8 +196,8 @@ static int count_refspec_match(const char *pattern,
|
||||
*/
|
||||
if (namelen != patlen &&
|
||||
patlen != namelen - 5 &&
|
||||
strncmp(name, "refs/heads/", 11) &&
|
||||
strncmp(name, "refs/tags/", 10)) {
|
||||
prefixcmp(name, "refs/heads/") &&
|
||||
prefixcmp(name, "refs/tags/")) {
|
||||
/* We want to catch the case where only weak
|
||||
* matches are found and there are multiple
|
||||
* matches, and where more than one strong
|
||||
|
@ -25,11 +25,14 @@ foreach my $tar_file (@ARGV)
|
||||
my $tar_name = $1;
|
||||
|
||||
if ($tar_name =~ s/\.(tar\.gz|tgz)$//) {
|
||||
open(I, '-|', 'gzcat', $tar_file) or die "Unable to gzcat $tar_file: $!\n";
|
||||
open(I, '-|', 'gunzip', '-c', $tar_file)
|
||||
or die "Unable to gunzip -c $tar_file: $!\n";
|
||||
} elsif ($tar_name =~ s/\.(tar\.bz2|tbz2)$//) {
|
||||
open(I, '-|', 'bzcat', $tar_file) or die "Unable to bzcat $tar_file: $!\n";
|
||||
open(I, '-|', 'bunzip2', '-c', $tar_file)
|
||||
or die "Unable to bunzip2 -c $tar_file: $!\n";
|
||||
} elsif ($tar_name =~ s/\.tar\.Z$//) {
|
||||
open(I, '-|', 'zcat', $tar_file) or die "Unable to zcat $tar_file: $!\n";
|
||||
open(I, '-|', 'uncompress', '-c', $tar_file)
|
||||
or die "Unable to uncompress -c $tar_file: $!\n";
|
||||
} elsif ($tar_name =~ s/\.tar$//) {
|
||||
open(I, $tar_file) or die "Unable to open $tar_file: $!\n";
|
||||
} else {
|
||||
|
186
convert.c
Normal file
186
convert.c
Normal file
@ -0,0 +1,186 @@
|
||||
#include "cache.h"
|
||||
/*
|
||||
* convert.c - convert a file when checking it out and checking it in.
|
||||
*
|
||||
* This should use the pathname to decide on whether it wants to do some
|
||||
* more interesting conversions (automatic gzip/unzip, general format
|
||||
* conversions etc etc), but by default it just does automatic CRLF<->LF
|
||||
* translation when the "auto_crlf" option is set.
|
||||
*/
|
||||
|
||||
struct text_stat {
|
||||
/* CR, LF and CRLF counts */
|
||||
unsigned cr, lf, crlf;
|
||||
|
||||
/* These are just approximations! */
|
||||
unsigned printable, nonprintable;
|
||||
};
|
||||
|
||||
static void gather_stats(const char *buf, unsigned long size, struct text_stat *stats)
|
||||
{
|
||||
unsigned long i;
|
||||
|
||||
memset(stats, 0, sizeof(*stats));
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
unsigned char c = buf[i];
|
||||
if (c == '\r') {
|
||||
stats->cr++;
|
||||
if (i+1 < size && buf[i+1] == '\n')
|
||||
stats->crlf++;
|
||||
continue;
|
||||
}
|
||||
if (c == '\n') {
|
||||
stats->lf++;
|
||||
continue;
|
||||
}
|
||||
if (c == 127)
|
||||
/* DEL */
|
||||
stats->nonprintable++;
|
||||
else if (c < 32) {
|
||||
switch (c) {
|
||||
/* BS, HT, ESC and FF */
|
||||
case '\b': case '\t': case '\033': case '\014':
|
||||
stats->printable++;
|
||||
break;
|
||||
default:
|
||||
stats->nonprintable++;
|
||||
}
|
||||
}
|
||||
else
|
||||
stats->printable++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The same heuristics as diff.c::mmfile_is_binary()
|
||||
*/
|
||||
static int is_binary(unsigned long size, struct text_stat *stats)
|
||||
{
|
||||
|
||||
if ((stats->printable >> 7) < stats->nonprintable)
|
||||
return 1;
|
||||
/*
|
||||
* Other heuristics? Average line length might be relevant,
|
||||
* as might LF vs CR vs CRLF counts..
|
||||
*
|
||||
* NOTE! It might be normal to have a low ratio of CRLF to LF
|
||||
* (somebody starts with a LF-only file and edits it with an editor
|
||||
* that adds CRLF only to lines that are added..). But do we
|
||||
* want to support CR-only? Probably not.
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
int convert_to_git(const char *path, char **bufp, unsigned long *sizep)
|
||||
{
|
||||
char *buffer, *nbuf;
|
||||
unsigned long size, nsize;
|
||||
struct text_stat stats;
|
||||
|
||||
/*
|
||||
* FIXME! Other pluggable conversions should go here,
|
||||
* based on filename patterns. Right now we just do the
|
||||
* stupid auto-CRLF one.
|
||||
*/
|
||||
if (!auto_crlf)
|
||||
return 0;
|
||||
|
||||
size = *sizep;
|
||||
if (!size)
|
||||
return 0;
|
||||
buffer = *bufp;
|
||||
|
||||
gather_stats(buffer, size, &stats);
|
||||
|
||||
/* No CR? Nothing to convert, regardless. */
|
||||
if (!stats.cr)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* We're currently not going to even try to convert stuff
|
||||
* that has bare CR characters. Does anybody do that crazy
|
||||
* stuff?
|
||||
*/
|
||||
if (stats.cr != stats.crlf)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* And add some heuristics for binary vs text, of course...
|
||||
*/
|
||||
if (is_binary(size, &stats))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Ok, allocate a new buffer, fill it in, and return true
|
||||
* to let the caller know that we switched buffers on it.
|
||||
*/
|
||||
nsize = size - stats.crlf;
|
||||
nbuf = xmalloc(nsize);
|
||||
*bufp = nbuf;
|
||||
*sizep = nsize;
|
||||
do {
|
||||
unsigned char c = *buffer++;
|
||||
if (c != '\r')
|
||||
*nbuf++ = c;
|
||||
} while (--size);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int convert_to_working_tree(const char *path, char **bufp, unsigned long *sizep)
|
||||
{
|
||||
char *buffer, *nbuf;
|
||||
unsigned long size, nsize;
|
||||
struct text_stat stats;
|
||||
unsigned char last;
|
||||
|
||||
/*
|
||||
* FIXME! Other pluggable conversions should go here,
|
||||
* based on filename patterns. Right now we just do the
|
||||
* stupid auto-CRLF one.
|
||||
*/
|
||||
if (auto_crlf <= 0)
|
||||
return 0;
|
||||
|
||||
size = *sizep;
|
||||
if (!size)
|
||||
return 0;
|
||||
buffer = *bufp;
|
||||
|
||||
gather_stats(buffer, size, &stats);
|
||||
|
||||
/* No LF? Nothing to convert, regardless. */
|
||||
if (!stats.lf)
|
||||
return 0;
|
||||
|
||||
/* Was it already in CRLF format? */
|
||||
if (stats.lf == stats.crlf)
|
||||
return 0;
|
||||
|
||||
/* If we have any bare CR characters, we're not going to touch it */
|
||||
if (stats.cr != stats.crlf)
|
||||
return 0;
|
||||
|
||||
if (is_binary(size, &stats))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Ok, allocate a new buffer, fill it in, and return true
|
||||
* to let the caller know that we switched buffers on it.
|
||||
*/
|
||||
nsize = size + stats.lf - stats.crlf;
|
||||
nbuf = xmalloc(nsize);
|
||||
*bufp = nbuf;
|
||||
*sizep = nsize;
|
||||
last = 0;
|
||||
do {
|
||||
unsigned char c = *buffer++;
|
||||
if (c == '\n' && last != '\r')
|
||||
*nbuf++ = '\r';
|
||||
*nbuf++ = c;
|
||||
last = c;
|
||||
} while (--size);
|
||||
|
||||
return 1;
|
||||
}
|
32
daemon.c
32
daemon.c
@ -286,7 +286,7 @@ static int service_enabled;
|
||||
|
||||
static int git_daemon_config(const char *var, const char *value)
|
||||
{
|
||||
if (!strncmp(var, "daemon.", 7) &&
|
||||
if (!prefixcmp(var, "daemon.") &&
|
||||
!strcmp(var + 7, service_looking_at->config_name)) {
|
||||
service_enabled = git_config_bool(var, value);
|
||||
return 0;
|
||||
@ -562,7 +562,7 @@ static int execute(struct sockaddr *addr)
|
||||
for (i = 0; i < ARRAY_SIZE(daemon_service); i++) {
|
||||
struct daemon_service *s = &(daemon_service[i]);
|
||||
int namelen = strlen(s->name);
|
||||
if (!strncmp("git-", line, 4) &&
|
||||
if (!prefixcmp(line, "git-") &&
|
||||
!strncmp(s->name, line + 4, namelen) &&
|
||||
line[namelen + 4] == ' ') {
|
||||
/*
|
||||
@ -1011,7 +1011,7 @@ int main(int argc, char **argv)
|
||||
for (i = 1; i < argc; i++) {
|
||||
char *arg = argv[i];
|
||||
|
||||
if (!strncmp(arg, "--listen=", 9)) {
|
||||
if (!prefixcmp(arg, "--listen=")) {
|
||||
char *p = arg + 9;
|
||||
char *ph = listen_addr = xmalloc(strlen(arg + 9) + 1);
|
||||
while (*p)
|
||||
@ -1019,7 +1019,7 @@ int main(int argc, char **argv)
|
||||
*ph = 0;
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(arg, "--port=", 7)) {
|
||||
if (!prefixcmp(arg, "--port=")) {
|
||||
char *end;
|
||||
unsigned long n;
|
||||
n = strtoul(arg+7, &end, 0);
|
||||
@ -1045,11 +1045,11 @@ int main(int argc, char **argv)
|
||||
export_all_trees = 1;
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(arg, "--timeout=", 10)) {
|
||||
if (!prefixcmp(arg, "--timeout=")) {
|
||||
timeout = atoi(arg+10);
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(arg, "--init-timeout=", 15)) {
|
||||
if (!prefixcmp(arg, "--init-timeout=")) {
|
||||
init_timeout = atoi(arg+15);
|
||||
continue;
|
||||
}
|
||||
@ -1057,11 +1057,11 @@ int main(int argc, char **argv)
|
||||
strict_paths = 1;
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(arg, "--base-path=", 12)) {
|
||||
if (!prefixcmp(arg, "--base-path=")) {
|
||||
base_path = arg+12;
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(arg, "--interpolated-path=", 20)) {
|
||||
if (!prefixcmp(arg, "--interpolated-path=")) {
|
||||
interpolated_path = arg+20;
|
||||
continue;
|
||||
}
|
||||
@ -1073,11 +1073,11 @@ int main(int argc, char **argv)
|
||||
user_path = "";
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(arg, "--user-path=", 12)) {
|
||||
if (!prefixcmp(arg, "--user-path=")) {
|
||||
user_path = arg + 12;
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(arg, "--pid-file=", 11)) {
|
||||
if (!prefixcmp(arg, "--pid-file=")) {
|
||||
pid_file = arg + 11;
|
||||
continue;
|
||||
}
|
||||
@ -1086,27 +1086,27 @@ int main(int argc, char **argv)
|
||||
log_syslog = 1;
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(arg, "--user=", 7)) {
|
||||
if (!prefixcmp(arg, "--user=")) {
|
||||
user_name = arg + 7;
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(arg, "--group=", 8)) {
|
||||
if (!prefixcmp(arg, "--group=")) {
|
||||
group_name = arg + 8;
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(arg, "--enable=", 9)) {
|
||||
if (!prefixcmp(arg, "--enable=")) {
|
||||
enable_service(arg + 9, 1);
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(arg, "--disable=", 10)) {
|
||||
if (!prefixcmp(arg, "--disable=")) {
|
||||
enable_service(arg + 10, 0);
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(arg, "--allow-override=", 17)) {
|
||||
if (!prefixcmp(arg, "--allow-override=")) {
|
||||
make_service_overridable(arg + 17, 1);
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(arg, "--forbid-override=", 18)) {
|
||||
if (!prefixcmp(arg, "--forbid-override=")) {
|
||||
make_service_overridable(arg + 18, 0);
|
||||
continue;
|
||||
}
|
||||
|
16
diff-lib.c
16
diff-lib.c
@ -248,17 +248,27 @@ int run_diff_files(struct rev_info *revs, int silent_on_removed)
|
||||
|
||||
path_len = ce_namelen(ce);
|
||||
|
||||
dpath = xmalloc (combine_diff_path_size (5, path_len));
|
||||
dpath = xmalloc(combine_diff_path_size(5, path_len));
|
||||
dpath->path = (char *) &(dpath->parent[5]);
|
||||
|
||||
dpath->next = NULL;
|
||||
dpath->len = path_len;
|
||||
memcpy(dpath->path, ce->name, path_len);
|
||||
dpath->path[path_len] = '\0';
|
||||
dpath->mode = 0;
|
||||
hashclr(dpath->sha1);
|
||||
memset(&(dpath->parent[0]), 0,
|
||||
sizeof(struct combine_diff_parent)*5);
|
||||
sizeof(struct combine_diff_parent)*5);
|
||||
|
||||
if (lstat(ce->name, &st) < 0) {
|
||||
if (errno != ENOENT && errno != ENOTDIR) {
|
||||
perror(ce->name);
|
||||
continue;
|
||||
}
|
||||
if (silent_on_removed)
|
||||
continue;
|
||||
}
|
||||
else
|
||||
dpath->mode = canon_mode(st.st_mode);
|
||||
|
||||
while (i < entries) {
|
||||
struct cache_entry *nce = active_cache[i];
|
||||
|
149
diff.c
149
diff.c
@ -77,7 +77,7 @@ int git_diff_ui_config(const char *var, const char *value)
|
||||
diff_detect_rename_default = DIFF_DETECT_RENAME;
|
||||
return 0;
|
||||
}
|
||||
if (!strncmp(var, "diff.color.", 11) || !strncmp(var, "color.diff.", 11)) {
|
||||
if (!prefixcmp(var, "diff.color.") || !prefixcmp(var, "color.diff.")) {
|
||||
int slot = parse_diff_color_slot(var, 11);
|
||||
color_parse(value, var, diff_colors[slot]);
|
||||
return 0;
|
||||
@ -184,31 +184,43 @@ static void print_line_count(int count)
|
||||
}
|
||||
}
|
||||
|
||||
static void copy_file(int prefix, const char *data, int size)
|
||||
static void copy_file(int prefix, const char *data, int size,
|
||||
const char *set, const char *reset)
|
||||
{
|
||||
int ch, nl_just_seen = 1;
|
||||
while (0 < size--) {
|
||||
ch = *data++;
|
||||
if (nl_just_seen)
|
||||
if (nl_just_seen) {
|
||||
fputs(set, stdout);
|
||||
putchar(prefix);
|
||||
putchar(ch);
|
||||
if (ch == '\n')
|
||||
}
|
||||
if (ch == '\n') {
|
||||
nl_just_seen = 1;
|
||||
else
|
||||
fputs(reset, stdout);
|
||||
} else
|
||||
nl_just_seen = 0;
|
||||
putchar(ch);
|
||||
}
|
||||
if (!nl_just_seen)
|
||||
printf("\n\\ No newline at end of file\n");
|
||||
printf("%s\n\\ No newline at end of file\n", reset);
|
||||
}
|
||||
|
||||
static void emit_rewrite_diff(const char *name_a,
|
||||
const char *name_b,
|
||||
struct diff_filespec *one,
|
||||
struct diff_filespec *two)
|
||||
struct diff_filespec *two,
|
||||
int color_diff)
|
||||
{
|
||||
int lc_a, lc_b;
|
||||
const char *name_a_tab, *name_b_tab;
|
||||
const char *metainfo = diff_get_color(color_diff, DIFF_METAINFO);
|
||||
const char *fraginfo = diff_get_color(color_diff, DIFF_FRAGINFO);
|
||||
const char *old = diff_get_color(color_diff, DIFF_FILE_OLD);
|
||||
const char *new = diff_get_color(color_diff, DIFF_FILE_NEW);
|
||||
const char *reset = diff_get_color(color_diff, DIFF_RESET);
|
||||
|
||||
name_a += (*name_a == '/');
|
||||
name_b += (*name_b == '/');
|
||||
name_a_tab = strchr(name_a, ' ') ? "\t" : "";
|
||||
name_b_tab = strchr(name_b, ' ') ? "\t" : "";
|
||||
|
||||
@ -216,17 +228,17 @@ static void emit_rewrite_diff(const char *name_a,
|
||||
diff_populate_filespec(two, 0);
|
||||
lc_a = count_lines(one->data, one->size);
|
||||
lc_b = count_lines(two->data, two->size);
|
||||
printf("--- a/%s%s\n+++ b/%s%s\n@@ -",
|
||||
name_a, name_a_tab,
|
||||
name_b, name_b_tab);
|
||||
printf("%s--- a/%s%s%s\n%s+++ b/%s%s%s\n%s@@ -",
|
||||
metainfo, name_a, name_a_tab, reset,
|
||||
metainfo, name_b, name_b_tab, reset, fraginfo);
|
||||
print_line_count(lc_a);
|
||||
printf(" +");
|
||||
print_line_count(lc_b);
|
||||
printf(" @@\n");
|
||||
printf(" @@%s\n", reset);
|
||||
if (lc_a)
|
||||
copy_file('-', one->data, one->size);
|
||||
copy_file('-', one->data, one->size, old, reset);
|
||||
if (lc_b)
|
||||
copy_file('+', two->data, two->size);
|
||||
copy_file('+', two->data, two->size, new, reset);
|
||||
}
|
||||
|
||||
static int fill_mmfile(mmfile_t *mf, struct diff_filespec *one)
|
||||
@ -405,22 +417,16 @@ static void emit_line(const char *set, const char *reset, const char *line, int
|
||||
puts(reset);
|
||||
}
|
||||
|
||||
static void emit_add_line(const char *reset, struct emit_callback *ecbdata, const char *line, int len)
|
||||
static void emit_line_with_ws(int nparents,
|
||||
const char *set, const char *reset, const char *ws,
|
||||
const char *line, int len)
|
||||
{
|
||||
int col0 = ecbdata->nparents;
|
||||
int col0 = nparents;
|
||||
int last_tab_in_indent = -1;
|
||||
int last_space_in_indent = -1;
|
||||
int i;
|
||||
int tail = len;
|
||||
int need_highlight_leading_space = 0;
|
||||
const char *ws = diff_get_color(ecbdata->color_diff, DIFF_WHITESPACE);
|
||||
const char *set = diff_get_color(ecbdata->color_diff, DIFF_FILE_NEW);
|
||||
|
||||
if (!*ws) {
|
||||
emit_line(set, reset, line, len);
|
||||
return;
|
||||
}
|
||||
|
||||
/* The line is a newly added line. Does it have funny leading
|
||||
* whitespaces? In indent, SP should never precede a TAB.
|
||||
*/
|
||||
@ -475,6 +481,18 @@ static void emit_add_line(const char *reset, struct emit_callback *ecbdata, cons
|
||||
emit_line(set, reset, line + i, len - i);
|
||||
}
|
||||
|
||||
static void emit_add_line(const char *reset, struct emit_callback *ecbdata, const char *line, int len)
|
||||
{
|
||||
const char *ws = diff_get_color(ecbdata->color_diff, DIFF_WHITESPACE);
|
||||
const char *set = diff_get_color(ecbdata->color_diff, DIFF_FILE_NEW);
|
||||
|
||||
if (!*ws)
|
||||
emit_line(set, reset, line, len);
|
||||
else
|
||||
emit_line_with_ws(ecbdata->nparents, set, reset, ws,
|
||||
line, len);
|
||||
}
|
||||
|
||||
static void fn_out_consume(void *priv, char *line, unsigned long len)
|
||||
{
|
||||
int i;
|
||||
@ -884,30 +902,44 @@ static void show_numstat(struct diffstat_t* data, struct diff_options *options)
|
||||
struct checkdiff_t {
|
||||
struct xdiff_emit_state xm;
|
||||
const char *filename;
|
||||
int lineno;
|
||||
int lineno, color_diff;
|
||||
};
|
||||
|
||||
static void checkdiff_consume(void *priv, char *line, unsigned long len)
|
||||
{
|
||||
struct checkdiff_t *data = priv;
|
||||
const char *ws = diff_get_color(data->color_diff, DIFF_WHITESPACE);
|
||||
const char *reset = diff_get_color(data->color_diff, DIFF_RESET);
|
||||
const char *set = diff_get_color(data->color_diff, DIFF_FILE_NEW);
|
||||
|
||||
if (line[0] == '+') {
|
||||
int i, spaces = 0;
|
||||
int i, spaces = 0, space_before_tab = 0, white_space_at_end = 0;
|
||||
|
||||
/* check space before tab */
|
||||
for (i = 1; i < len && (line[i] == ' ' || line[i] == '\t'); i++)
|
||||
if (line[i] == ' ')
|
||||
spaces++;
|
||||
if (line[i - 1] == '\t' && spaces)
|
||||
printf("%s:%d: space before tab:%.*s\n",
|
||||
data->filename, data->lineno, (int)len, line);
|
||||
space_before_tab = 1;
|
||||
|
||||
/* check white space at line end */
|
||||
if (line[len - 1] == '\n')
|
||||
len--;
|
||||
if (isspace(line[len - 1]))
|
||||
printf("%s:%d: white space at end: %.*s\n",
|
||||
data->filename, data->lineno, (int)len, line);
|
||||
white_space_at_end = 1;
|
||||
|
||||
if (space_before_tab || white_space_at_end) {
|
||||
printf("%s:%d: %s", data->filename, data->lineno, ws);
|
||||
if (space_before_tab) {
|
||||
printf("space before tab");
|
||||
if (white_space_at_end)
|
||||
putchar(',');
|
||||
}
|
||||
if (white_space_at_end)
|
||||
printf("white space at end");
|
||||
printf(":%s ", reset);
|
||||
emit_line_with_ws(1, set, reset, ws, line, len);
|
||||
}
|
||||
|
||||
data->lineno++;
|
||||
} else if (line[0] == ' ')
|
||||
@ -1034,8 +1066,8 @@ static void builtin_diff(const char *name_a,
|
||||
const char *set = diff_get_color(o->color_diff, DIFF_METAINFO);
|
||||
const char *reset = diff_get_color(o->color_diff, DIFF_RESET);
|
||||
|
||||
a_one = quote_two("a/", name_a);
|
||||
b_two = quote_two("b/", name_b);
|
||||
a_one = quote_two("a/", name_a + (*name_a == '/'));
|
||||
b_two = quote_two("b/", name_b + (*name_b == '/'));
|
||||
lbl[0] = DIFF_FILE_VALID(one) ? a_one : "/dev/null";
|
||||
lbl[1] = DIFF_FILE_VALID(two) ? b_two : "/dev/null";
|
||||
printf("%sdiff --git %s %s%s\n", set, a_one, b_two, reset);
|
||||
@ -1064,7 +1096,8 @@ static void builtin_diff(const char *name_a,
|
||||
if ((one->mode ^ two->mode) & S_IFMT)
|
||||
goto free_ab_and_return;
|
||||
if (complete_rewrite) {
|
||||
emit_rewrite_diff(name_a, name_b, one, two);
|
||||
emit_rewrite_diff(name_a, name_b, one, two,
|
||||
o->color_diff);
|
||||
goto free_ab_and_return;
|
||||
}
|
||||
}
|
||||
@ -1099,9 +1132,9 @@ static void builtin_diff(const char *name_a,
|
||||
xecfg.flags = XDL_EMIT_FUNCNAMES;
|
||||
if (!diffopts)
|
||||
;
|
||||
else if (!strncmp(diffopts, "--unified=", 10))
|
||||
else if (!prefixcmp(diffopts, "--unified="))
|
||||
xecfg.ctxlen = strtoul(diffopts + 10, NULL, 10);
|
||||
else if (!strncmp(diffopts, "-u", 2))
|
||||
else if (!prefixcmp(diffopts, "-u"))
|
||||
xecfg.ctxlen = strtoul(diffopts + 2, NULL, 10);
|
||||
ecb.outf = xdiff_outf;
|
||||
ecb.priv = &ecbdata;
|
||||
@ -1165,7 +1198,7 @@ static void builtin_diffstat(const char *name_a, const char *name_b,
|
||||
|
||||
static void builtin_checkdiff(const char *name_a, const char *name_b,
|
||||
struct diff_filespec *one,
|
||||
struct diff_filespec *two)
|
||||
struct diff_filespec *two, struct diff_options *o)
|
||||
{
|
||||
mmfile_t mf1, mf2;
|
||||
struct checkdiff_t data;
|
||||
@ -1177,6 +1210,7 @@ static void builtin_checkdiff(const char *name_a, const char *name_b,
|
||||
data.xm.consume = checkdiff_consume;
|
||||
data.filename = name_b ? name_b : name_a;
|
||||
data.lineno = 0;
|
||||
data.color_diff = o->color_diff;
|
||||
|
||||
if (fill_mmfile(&mf1, one) < 0 || fill_mmfile(&mf2, two) < 0)
|
||||
die("unable to read files to diff");
|
||||
@ -1346,6 +1380,9 @@ int diff_populate_filespec(struct diff_filespec *s, int size_only)
|
||||
reuse_worktree_file(s->path, s->sha1, 0)) {
|
||||
struct stat st;
|
||||
int fd;
|
||||
char *buf;
|
||||
unsigned long size;
|
||||
|
||||
if (lstat(s->path, &st) < 0) {
|
||||
if (errno == ENOENT) {
|
||||
err_empty:
|
||||
@ -1378,7 +1415,19 @@ int diff_populate_filespec(struct diff_filespec *s, int size_only)
|
||||
s->data = xmmap(NULL, s->size, PROT_READ, MAP_PRIVATE, fd, 0);
|
||||
close(fd);
|
||||
s->should_munmap = 1;
|
||||
/* FIXME! CRLF -> LF conversion goes here, based on "s->path" */
|
||||
|
||||
/*
|
||||
* Convert from working tree format to canonical git format
|
||||
*/
|
||||
buf = s->data;
|
||||
size = s->size;
|
||||
if (convert_to_git(s->path, &buf, &size)) {
|
||||
munmap(s->data, s->size);
|
||||
s->should_munmap = 0;
|
||||
s->data = buf;
|
||||
s->size = size;
|
||||
s->should_free = 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
char type[20];
|
||||
@ -1787,7 +1836,7 @@ static void run_checkdiff(struct diff_filepair *p, struct diff_options *o)
|
||||
diff_fill_sha1_info(p->one);
|
||||
diff_fill_sha1_info(p->two);
|
||||
|
||||
builtin_checkdiff(name, other, p->one, p->two);
|
||||
builtin_checkdiff(name, other, p->one, p->two, o);
|
||||
}
|
||||
|
||||
void diff_setup(struct diff_options *options)
|
||||
@ -1936,7 +1985,7 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac)
|
||||
else if (!strcmp(arg, "--shortstat")) {
|
||||
options->output_format |= DIFF_FORMAT_SHORTSTAT;
|
||||
}
|
||||
else if (!strncmp(arg, "--stat", 6)) {
|
||||
else if (!prefixcmp(arg, "--stat")) {
|
||||
char *end;
|
||||
int width = options->stat_width;
|
||||
int name_width = options->stat_name_width;
|
||||
@ -1945,9 +1994,9 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac)
|
||||
|
||||
switch (*arg) {
|
||||
case '-':
|
||||
if (!strncmp(arg, "-width=", 7))
|
||||
if (!prefixcmp(arg, "-width="))
|
||||
width = strtoul(arg + 7, &end, 10);
|
||||
else if (!strncmp(arg, "-name-width=", 12))
|
||||
else if (!prefixcmp(arg, "-name-width="))
|
||||
name_width = strtoul(arg + 12, &end, 10);
|
||||
break;
|
||||
case '=':
|
||||
@ -1972,7 +2021,7 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac)
|
||||
}
|
||||
else if (!strcmp(arg, "-z"))
|
||||
options->line_termination = 0;
|
||||
else if (!strncmp(arg, "-l", 2))
|
||||
else if (!prefixcmp(arg, "-l"))
|
||||
options->rename_limit = strtoul(arg+2, NULL, 10);
|
||||
else if (!strcmp(arg, "--full-index"))
|
||||
options->full_index = 1;
|
||||
@ -1989,31 +2038,31 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac)
|
||||
options->output_format |= DIFF_FORMAT_NAME_STATUS;
|
||||
else if (!strcmp(arg, "-R"))
|
||||
options->reverse_diff = 1;
|
||||
else if (!strncmp(arg, "-S", 2))
|
||||
else if (!prefixcmp(arg, "-S"))
|
||||
options->pickaxe = arg + 2;
|
||||
else if (!strcmp(arg, "-s")) {
|
||||
options->output_format |= DIFF_FORMAT_NO_OUTPUT;
|
||||
}
|
||||
else if (!strncmp(arg, "-O", 2))
|
||||
else if (!prefixcmp(arg, "-O"))
|
||||
options->orderfile = arg + 2;
|
||||
else if (!strncmp(arg, "--diff-filter=", 14))
|
||||
else if (!prefixcmp(arg, "--diff-filter="))
|
||||
options->filter = arg + 14;
|
||||
else if (!strcmp(arg, "--pickaxe-all"))
|
||||
options->pickaxe_opts = DIFF_PICKAXE_ALL;
|
||||
else if (!strcmp(arg, "--pickaxe-regex"))
|
||||
options->pickaxe_opts = DIFF_PICKAXE_REGEX;
|
||||
else if (!strncmp(arg, "-B", 2)) {
|
||||
else if (!prefixcmp(arg, "-B")) {
|
||||
if ((options->break_opt =
|
||||
diff_scoreopt_parse(arg)) == -1)
|
||||
return -1;
|
||||
}
|
||||
else if (!strncmp(arg, "-M", 2)) {
|
||||
else if (!prefixcmp(arg, "-M")) {
|
||||
if ((options->rename_score =
|
||||
diff_scoreopt_parse(arg)) == -1)
|
||||
return -1;
|
||||
options->detect_rename = DIFF_DETECT_RENAME;
|
||||
}
|
||||
else if (!strncmp(arg, "-C", 2)) {
|
||||
else if (!prefixcmp(arg, "-C")) {
|
||||
if ((options->rename_score =
|
||||
diff_scoreopt_parse(arg)) == -1)
|
||||
return -1;
|
||||
@ -2023,7 +2072,7 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac)
|
||||
options->find_copies_harder = 1;
|
||||
else if (!strcmp(arg, "--abbrev"))
|
||||
options->abbrev = DEFAULT_ABBREV;
|
||||
else if (!strncmp(arg, "--abbrev=", 9)) {
|
||||
else if (!prefixcmp(arg, "--abbrev=")) {
|
||||
options->abbrev = strtoul(arg + 9, NULL, 10);
|
||||
if (options->abbrev < MINIMUM_ABBREV)
|
||||
options->abbrev = MINIMUM_ABBREV;
|
||||
@ -2533,7 +2582,7 @@ static void patch_id_consume(void *priv, char *line, unsigned long len)
|
||||
int new_len;
|
||||
|
||||
/* Ignore line numbers when computing the SHA1 of the patch */
|
||||
if (!strncmp(line, "@@ -", 4))
|
||||
if (!prefixcmp(line, "@@ -"))
|
||||
return;
|
||||
|
||||
new_len = remove_space(line, len);
|
||||
|
16
entry.c
16
entry.c
@ -78,6 +78,9 @@ static int write_entry(struct cache_entry *ce, char *path, struct checkout *stat
|
||||
path, sha1_to_hex(ce->sha1));
|
||||
}
|
||||
switch (ntohl(ce->ce_mode) & S_IFMT) {
|
||||
char *buf;
|
||||
unsigned long nsize;
|
||||
|
||||
case S_IFREG:
|
||||
if (to_tempfile) {
|
||||
strcpy(path, ".merge_file_XXXXXX");
|
||||
@ -89,7 +92,18 @@ static int write_entry(struct cache_entry *ce, char *path, struct checkout *stat
|
||||
return error("git-checkout-index: unable to create file %s (%s)",
|
||||
path, strerror(errno));
|
||||
}
|
||||
/* FIXME: LF -> CRLF conversion goes here, based on "ce->name" */
|
||||
|
||||
/*
|
||||
* Convert from git internal format to working tree format
|
||||
*/
|
||||
buf = new;
|
||||
nsize = size;
|
||||
if (convert_to_working_tree(ce->name, &buf, &nsize)) {
|
||||
free(new);
|
||||
new = buf;
|
||||
size = nsize;
|
||||
}
|
||||
|
||||
wrote = write_in_full(fd, new, size);
|
||||
close(fd);
|
||||
free(new);
|
||||
|
@ -28,6 +28,7 @@ size_t packed_git_window_size = DEFAULT_PACKED_GIT_WINDOW_SIZE;
|
||||
size_t packed_git_limit = DEFAULT_PACKED_GIT_LIMIT;
|
||||
int pager_in_use;
|
||||
int pager_use_color = 1;
|
||||
int auto_crlf = 0; /* 1: both ways, -1: only when adding git objects */
|
||||
|
||||
static const char *git_dir;
|
||||
static char *git_object_dir, *git_index_file, *git_refs_dir, *git_graft_file;
|
||||
|
@ -56,7 +56,7 @@ int execv_git_cmd(const char **argv)
|
||||
len = strlen(git_command);
|
||||
|
||||
/* Trivial cleanup */
|
||||
while (!strncmp(exec_dir, "./", 2)) {
|
||||
while (!prefixcmp(exec_dir, "./")) {
|
||||
exec_dir += 2;
|
||||
while (*exec_dir == '/')
|
||||
exec_dir++;
|
||||
|
@ -133,6 +133,10 @@ Format of STDIN stream:
|
||||
#define PACK_ID_BITS 16
|
||||
#define MAX_PACK_ID ((1<<PACK_ID_BITS)-1)
|
||||
|
||||
#ifndef PRIuMAX
|
||||
#define PRIuMAX "llu"
|
||||
#endif
|
||||
|
||||
struct object_entry
|
||||
{
|
||||
struct object_entry *next;
|
||||
@ -475,7 +479,7 @@ static struct object_entry *find_mark(uintmax_t idnum)
|
||||
oe = s->data.marked[idnum];
|
||||
}
|
||||
if (!oe)
|
||||
die("mark :%ju not declared", orig_idnum);
|
||||
die("mark :%" PRIuMAX " not declared", orig_idnum);
|
||||
return oe;
|
||||
}
|
||||
|
||||
@ -1361,7 +1365,7 @@ static void dump_marks_helper(FILE *f,
|
||||
} else {
|
||||
for (k = 0; k < 1024; k++) {
|
||||
if (m->data.marked[k])
|
||||
fprintf(f, ":%ju %s\n", base + k,
|
||||
fprintf(f, ":%" PRIuMAX " %s\n", base + k,
|
||||
sha1_to_hex(m->data.marked[k]->sha1));
|
||||
}
|
||||
}
|
||||
@ -1388,7 +1392,7 @@ static void read_next_command(void)
|
||||
|
||||
static void cmd_mark(void)
|
||||
{
|
||||
if (!strncmp("mark :", command_buf.buf, 6)) {
|
||||
if (!prefixcmp(command_buf.buf, "mark :")) {
|
||||
next_mark = strtoumax(command_buf.buf + 6, NULL, 10);
|
||||
read_next_command();
|
||||
}
|
||||
@ -1401,10 +1405,10 @@ static void *cmd_data (size_t *size)
|
||||
size_t length;
|
||||
char *buffer;
|
||||
|
||||
if (strncmp("data ", command_buf.buf, 5))
|
||||
if (prefixcmp(command_buf.buf, "data "))
|
||||
die("Expected 'data n' command, found: %s", command_buf.buf);
|
||||
|
||||
if (!strncmp("<<", command_buf.buf + 5, 2)) {
|
||||
if (!prefixcmp(command_buf.buf + 5, "<<")) {
|
||||
char *term = xstrdup(command_buf.buf + 5 + 2);
|
||||
size_t sz = 8192, term_len = command_buf.len - 5 - 2;
|
||||
length = 0;
|
||||
@ -1591,7 +1595,7 @@ static void file_change_m(struct branch *b)
|
||||
oe = find_mark(strtoumax(p + 1, &x, 10));
|
||||
hashcpy(sha1, oe->sha1);
|
||||
p = x;
|
||||
} else if (!strncmp("inline", p, 6)) {
|
||||
} else if (!prefixcmp(p, "inline")) {
|
||||
inline_data = 1;
|
||||
p += 6;
|
||||
} else {
|
||||
@ -1664,7 +1668,7 @@ static void cmd_from(struct branch *b)
|
||||
const char *from;
|
||||
struct branch *s;
|
||||
|
||||
if (strncmp("from ", command_buf.buf, 5))
|
||||
if (prefixcmp(command_buf.buf, "from "))
|
||||
return;
|
||||
|
||||
if (b->branch_tree.tree) {
|
||||
@ -1687,7 +1691,7 @@ static void cmd_from(struct branch *b)
|
||||
unsigned long size;
|
||||
char *buf;
|
||||
if (oe->type != OBJ_COMMIT)
|
||||
die("Mark :%ju not a commit", idnum);
|
||||
die("Mark :%" PRIuMAX " not a commit", idnum);
|
||||
hashcpy(b->sha1, oe->sha1);
|
||||
buf = gfi_unpack_entry(oe, &size);
|
||||
if (!buf || size < 46)
|
||||
@ -1730,7 +1734,7 @@ static struct hash_list *cmd_merge(unsigned int *count)
|
||||
struct branch *s;
|
||||
|
||||
*count = 0;
|
||||
while (!strncmp("merge ", command_buf.buf, 6)) {
|
||||
while (!prefixcmp(command_buf.buf, "merge ")) {
|
||||
from = strchr(command_buf.buf, ' ') + 1;
|
||||
n = xmalloc(sizeof(*n));
|
||||
s = lookup_branch(from);
|
||||
@ -1740,7 +1744,7 @@ static struct hash_list *cmd_merge(unsigned int *count)
|
||||
uintmax_t idnum = strtoumax(from + 1, NULL, 10);
|
||||
struct object_entry *oe = find_mark(idnum);
|
||||
if (oe->type != OBJ_COMMIT)
|
||||
die("Mark :%ju not a commit", idnum);
|
||||
die("Mark :%" PRIuMAX " not a commit", idnum);
|
||||
hashcpy(n->sha1, oe->sha1);
|
||||
} else if (get_sha1(from, n->sha1))
|
||||
die("Invalid ref name or SHA1 expression: %s", from);
|
||||
@ -1776,11 +1780,11 @@ static void cmd_new_commit(void)
|
||||
|
||||
read_next_command();
|
||||
cmd_mark();
|
||||
if (!strncmp("author ", command_buf.buf, 7)) {
|
||||
if (!prefixcmp(command_buf.buf, "author ")) {
|
||||
author = parse_ident(command_buf.buf + 7);
|
||||
read_next_command();
|
||||
}
|
||||
if (!strncmp("committer ", command_buf.buf, 10)) {
|
||||
if (!prefixcmp(command_buf.buf, "committer ")) {
|
||||
committer = parse_ident(command_buf.buf + 10);
|
||||
read_next_command();
|
||||
}
|
||||
@ -1801,9 +1805,9 @@ static void cmd_new_commit(void)
|
||||
for (;;) {
|
||||
if (1 == command_buf.len)
|
||||
break;
|
||||
else if (!strncmp("M ", command_buf.buf, 2))
|
||||
else if (!prefixcmp(command_buf.buf, "M "))
|
||||
file_change_m(b);
|
||||
else if (!strncmp("D ", command_buf.buf, 2))
|
||||
else if (!prefixcmp(command_buf.buf, "D "))
|
||||
file_change_d(b);
|
||||
else if (!strcmp("deleteall", command_buf.buf))
|
||||
file_change_deleteall(b);
|
||||
@ -1873,7 +1877,7 @@ static void cmd_new_tag(void)
|
||||
read_next_command();
|
||||
|
||||
/* from ... */
|
||||
if (strncmp("from ", command_buf.buf, 5))
|
||||
if (prefixcmp(command_buf.buf, "from "))
|
||||
die("Expected from command, got %s", command_buf.buf);
|
||||
from = strchr(command_buf.buf, ' ') + 1;
|
||||
s = lookup_branch(from);
|
||||
@ -1884,7 +1888,7 @@ static void cmd_new_tag(void)
|
||||
from_mark = strtoumax(from + 1, NULL, 10);
|
||||
oe = find_mark(from_mark);
|
||||
if (oe->type != OBJ_COMMIT)
|
||||
die("Mark :%ju not a commit", from_mark);
|
||||
die("Mark :%" PRIuMAX " not a commit", from_mark);
|
||||
hashcpy(sha1, oe->sha1);
|
||||
} else if (!get_sha1(from, sha1)) {
|
||||
unsigned long size;
|
||||
@ -1900,7 +1904,7 @@ static void cmd_new_tag(void)
|
||||
read_next_command();
|
||||
|
||||
/* tagger ... */
|
||||
if (strncmp("tagger ", command_buf.buf, 7))
|
||||
if (prefixcmp(command_buf.buf, "tagger "))
|
||||
die("Expected tagger command, got %s", command_buf.buf);
|
||||
tagger = parse_ident(command_buf.buf + 7);
|
||||
|
||||
@ -1977,7 +1981,7 @@ int main(int argc, const char **argv)
|
||||
|
||||
if (*a != '-' || !strcmp(a, "--"))
|
||||
break;
|
||||
else if (!strncmp(a, "--date-format=", 14)) {
|
||||
else if (!prefixcmp(a, "--date-format=")) {
|
||||
const char *fmt = a + 14;
|
||||
if (!strcmp(fmt, "raw"))
|
||||
whenspec = WHENSPEC_RAW;
|
||||
@ -1988,15 +1992,15 @@ int main(int argc, const char **argv)
|
||||
else
|
||||
die("unknown --date-format argument %s", fmt);
|
||||
}
|
||||
else if (!strncmp(a, "--max-pack-size=", 16))
|
||||
else if (!prefixcmp(a, "--max-pack-size="))
|
||||
max_packsize = strtoumax(a + 16, NULL, 0) * 1024 * 1024;
|
||||
else if (!strncmp(a, "--depth=", 8))
|
||||
else if (!prefixcmp(a, "--depth="))
|
||||
max_depth = strtoul(a + 8, NULL, 0);
|
||||
else if (!strncmp(a, "--active-branches=", 18))
|
||||
else if (!prefixcmp(a, "--active-branches="))
|
||||
max_active_branches = strtoul(a + 18, NULL, 0);
|
||||
else if (!strncmp(a, "--export-marks=", 15))
|
||||
else if (!prefixcmp(a, "--export-marks="))
|
||||
mark_file = a + 15;
|
||||
else if (!strncmp(a, "--export-pack-edges=", 20)) {
|
||||
else if (!prefixcmp(a, "--export-pack-edges=")) {
|
||||
if (pack_edges)
|
||||
fclose(pack_edges);
|
||||
pack_edges = fopen(a + 20, "a");
|
||||
@ -2029,11 +2033,11 @@ int main(int argc, const char **argv)
|
||||
break;
|
||||
else if (!strcmp("blob", command_buf.buf))
|
||||
cmd_new_blob();
|
||||
else if (!strncmp("commit ", command_buf.buf, 7))
|
||||
else if (!prefixcmp(command_buf.buf, "commit "))
|
||||
cmd_new_commit();
|
||||
else if (!strncmp("tag ", command_buf.buf, 4))
|
||||
else if (!prefixcmp(command_buf.buf, "tag "))
|
||||
cmd_new_tag();
|
||||
else if (!strncmp("reset ", command_buf.buf, 6))
|
||||
else if (!prefixcmp(command_buf.buf, "reset "))
|
||||
cmd_reset_branch();
|
||||
else if (!strcmp("checkpoint", command_buf.buf))
|
||||
cmd_checkpoint();
|
||||
@ -2059,18 +2063,18 @@ int main(int argc, const char **argv)
|
||||
|
||||
fprintf(stderr, "%s statistics:\n", argv[0]);
|
||||
fprintf(stderr, "---------------------------------------------------------------------\n");
|
||||
fprintf(stderr, "Alloc'd objects: %10ju\n", alloc_count);
|
||||
fprintf(stderr, "Total objects: %10ju (%10ju duplicates )\n", total_count, duplicate_count);
|
||||
fprintf(stderr, " blobs : %10ju (%10ju duplicates %10ju deltas)\n", object_count_by_type[OBJ_BLOB], duplicate_count_by_type[OBJ_BLOB], delta_count_by_type[OBJ_BLOB]);
|
||||
fprintf(stderr, " trees : %10ju (%10ju duplicates %10ju deltas)\n", object_count_by_type[OBJ_TREE], duplicate_count_by_type[OBJ_TREE], delta_count_by_type[OBJ_TREE]);
|
||||
fprintf(stderr, " commits: %10ju (%10ju duplicates %10ju deltas)\n", object_count_by_type[OBJ_COMMIT], duplicate_count_by_type[OBJ_COMMIT], delta_count_by_type[OBJ_COMMIT]);
|
||||
fprintf(stderr, " tags : %10ju (%10ju duplicates %10ju deltas)\n", object_count_by_type[OBJ_TAG], duplicate_count_by_type[OBJ_TAG], delta_count_by_type[OBJ_TAG]);
|
||||
fprintf(stderr, "Alloc'd objects: %10" PRIuMAX "\n", alloc_count);
|
||||
fprintf(stderr, "Total objects: %10" PRIuMAX " (%10" PRIuMAX " duplicates )\n", total_count, duplicate_count);
|
||||
fprintf(stderr, " blobs : %10" PRIuMAX " (%10" PRIuMAX " duplicates %10" PRIuMAX " deltas)\n", object_count_by_type[OBJ_BLOB], duplicate_count_by_type[OBJ_BLOB], delta_count_by_type[OBJ_BLOB]);
|
||||
fprintf(stderr, " trees : %10" PRIuMAX " (%10" PRIuMAX " duplicates %10" PRIuMAX " deltas)\n", object_count_by_type[OBJ_TREE], duplicate_count_by_type[OBJ_TREE], delta_count_by_type[OBJ_TREE]);
|
||||
fprintf(stderr, " commits: %10" PRIuMAX " (%10" PRIuMAX " duplicates %10" PRIuMAX " deltas)\n", object_count_by_type[OBJ_COMMIT], duplicate_count_by_type[OBJ_COMMIT], delta_count_by_type[OBJ_COMMIT]);
|
||||
fprintf(stderr, " tags : %10" PRIuMAX " (%10" PRIuMAX " duplicates %10" PRIuMAX " deltas)\n", object_count_by_type[OBJ_TAG], duplicate_count_by_type[OBJ_TAG], delta_count_by_type[OBJ_TAG]);
|
||||
fprintf(stderr, "Total branches: %10lu (%10lu loads )\n", branch_count, branch_load_count);
|
||||
fprintf(stderr, " marks: %10ju (%10ju unique )\n", (((uintmax_t)1) << marks->shift) * 1024, marks_set_count);
|
||||
fprintf(stderr, " marks: %10" PRIuMAX " (%10" PRIuMAX " unique )\n", (((uintmax_t)1) << marks->shift) * 1024, marks_set_count);
|
||||
fprintf(stderr, " atoms: %10u\n", atom_cnt);
|
||||
fprintf(stderr, "Memory total: %10ju KiB\n", (total_allocd + alloc_count*sizeof(struct object_entry))/1024);
|
||||
fprintf(stderr, "Memory total: %10" PRIuMAX " KiB\n", (total_allocd + alloc_count*sizeof(struct object_entry))/1024);
|
||||
fprintf(stderr, " pools: %10lu KiB\n", (unsigned long)(total_allocd/1024));
|
||||
fprintf(stderr, " objects: %10ju KiB\n", (alloc_count*sizeof(struct object_entry))/1024);
|
||||
fprintf(stderr, " objects: %10" PRIuMAX " KiB\n", (alloc_count*sizeof(struct object_entry))/1024);
|
||||
fprintf(stderr, "---------------------------------------------------------------------\n");
|
||||
pack_report();
|
||||
fprintf(stderr, "---------------------------------------------------------------------\n");
|
||||
|
12
fetch-pack.c
12
fetch-pack.c
@ -198,13 +198,13 @@ static int find_common(int fd[2], unsigned char *result_sha1,
|
||||
int len;
|
||||
|
||||
while ((len = packet_read_line(fd[0], line, sizeof(line)))) {
|
||||
if (!strncmp("shallow ", line, 8)) {
|
||||
if (!prefixcmp(line, "shallow ")) {
|
||||
if (get_sha1_hex(line + 8, sha1))
|
||||
die("invalid shallow line: %s", line);
|
||||
register_shallow(sha1);
|
||||
continue;
|
||||
}
|
||||
if (!strncmp("unshallow ", line, 10)) {
|
||||
if (!prefixcmp(line, "unshallow ")) {
|
||||
if (get_sha1_hex(line + 10, sha1))
|
||||
die("invalid unshallow line: %s", line);
|
||||
if (!lookup_object(sha1))
|
||||
@ -346,7 +346,7 @@ static void filter_refs(struct ref **refs, int nr_match, char **match)
|
||||
check_ref_format(ref->name + 5))
|
||||
; /* trash */
|
||||
else if (fetch_all &&
|
||||
(!depth || strncmp(ref->name, "refs/tags/", 10) )) {
|
||||
(!depth || prefixcmp(ref->name, "refs/tags/") )) {
|
||||
*newtail = ref;
|
||||
ref->next = NULL;
|
||||
newtail = &ref->next;
|
||||
@ -683,11 +683,11 @@ int main(int argc, char **argv)
|
||||
char *arg = argv[i];
|
||||
|
||||
if (*arg == '-') {
|
||||
if (!strncmp("--upload-pack=", arg, 14)) {
|
||||
if (!prefixcmp(arg, "--upload-pack=")) {
|
||||
uploadpack = arg + 14;
|
||||
continue;
|
||||
}
|
||||
if (!strncmp("--exec=", arg, 7)) {
|
||||
if (!prefixcmp(arg, "--exec=")) {
|
||||
uploadpack = arg + 7;
|
||||
continue;
|
||||
}
|
||||
@ -712,7 +712,7 @@ int main(int argc, char **argv)
|
||||
verbose = 1;
|
||||
continue;
|
||||
}
|
||||
if (!strncmp("--depth=", arg, 8)) {
|
||||
if (!prefixcmp(arg, "--depth=")) {
|
||||
depth = strtol(arg + 8, NULL, 0);
|
||||
if (stat(git_path("shallow"), &st))
|
||||
st.st_mtime = 0;
|
||||
|
@ -66,7 +66,7 @@ fall_back_3way () {
|
||||
git-update-index -z --index-info <"$dotest/patch-merge-index-info" &&
|
||||
GIT_INDEX_FILE="$dotest/patch-merge-tmp-index" \
|
||||
git-write-tree >"$dotest/patch-merge-base+" ||
|
||||
cannot_fallback "Patch does not record usable index information."
|
||||
cannot_fallback "Repository lacks necessary blobs to fall back on 3-way merge."
|
||||
|
||||
echo Using index info to reconstruct a base tree...
|
||||
if GIT_INDEX_FILE="$dotest/patch-merge-tmp-index" \
|
||||
|
@ -318,6 +318,10 @@ esac
|
||||
|
||||
case "$all,$also" in
|
||||
t,)
|
||||
if test ! -f "$THIS_INDEX"
|
||||
then
|
||||
die 'nothing to commit (use "git add file1 file2" to include for commit)'
|
||||
fi
|
||||
save_index &&
|
||||
(
|
||||
cd_to_toplevel &&
|
||||
|
@ -1,6 +1,8 @@
|
||||
#ifndef GIT_COMPAT_UTIL_H
|
||||
#define GIT_COMPAT_UTIL_H
|
||||
|
||||
#define _FILE_OFFSET_BITS 64
|
||||
|
||||
#ifndef FLEX_ARRAY
|
||||
#if defined(__GNUC__) && (__GNUC__ < 3)
|
||||
#define FLEX_ARRAY 0
|
||||
@ -139,6 +141,11 @@ extern char *gitstrcasestr(const char *haystack, const char *needle);
|
||||
extern size_t gitstrlcpy(char *, const char *, size_t);
|
||||
#endif
|
||||
|
||||
#ifdef NO_STRTOUMAX
|
||||
#define strtoumax gitstrtoumax
|
||||
extern uintmax_t gitstrtoumax(const char *, char **, int);
|
||||
#endif
|
||||
|
||||
extern void release_pack_memory(size_t);
|
||||
|
||||
static inline char* xstrdup(const char *str)
|
||||
@ -274,4 +281,9 @@ static inline int sane_case(int x, int high)
|
||||
return x;
|
||||
}
|
||||
|
||||
static inline int prefixcmp(const char *str, const char *prefix)
|
||||
{
|
||||
return strncmp(str, prefix, strlen(prefix));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -15,14 +15,21 @@ unless ($ENV{GIT_DIR} && -r $ENV{GIT_DIR}){
|
||||
die "GIT_DIR is not defined or is unreadable";
|
||||
}
|
||||
|
||||
our ($opt_h, $opt_P, $opt_p, $opt_v, $opt_c, $opt_f, $opt_a, $opt_m );
|
||||
our ($opt_h, $opt_P, $opt_p, $opt_v, $opt_c, $opt_f, $opt_a, $opt_m, $opt_d);
|
||||
|
||||
getopts('hPpvcfam:');
|
||||
getopts('hPpvcfam:d:');
|
||||
|
||||
$opt_h && usage();
|
||||
|
||||
die "Need at least one commit identifier!" unless @ARGV;
|
||||
|
||||
my @cvs;
|
||||
if ($opt_d) {
|
||||
@cvs = ('cvs', '-d', $opt_d);
|
||||
} else {
|
||||
@cvs = ('cvs');
|
||||
}
|
||||
|
||||
# setup a tempdir
|
||||
our ($tmpdir, $tmpdirname) = tempdir('git-cvsapplycommit-XXXXXX',
|
||||
TMPDIR => 1,
|
||||
@ -160,7 +167,7 @@ foreach my $f (@afiles) {
|
||||
my $p = $1;
|
||||
next if (grep { $_ eq $p } @dirs);
|
||||
}
|
||||
my @status = grep(m/^File/, safe_pipe_capture('cvs', '-q', 'status' ,$f));
|
||||
my @status = grep(m/^File/, safe_pipe_capture(@cvs, '-q', 'status' ,$f));
|
||||
if (@status > 1) { warn 'Strange! cvs status returned more than one line?'};
|
||||
if (-d dirname $f and $status[0] !~ m/Status: Unknown$/
|
||||
and $status[0] !~ m/^File: no file /) {
|
||||
@ -173,7 +180,7 @@ foreach my $f (@afiles) {
|
||||
foreach my $f (@files) {
|
||||
next if grep { $_ eq $f } @afiles;
|
||||
# TODO:we need to handle removed in cvs
|
||||
my @status = grep(m/^File/, safe_pipe_capture('cvs', '-q', 'status' ,$f));
|
||||
my @status = grep(m/^File/, safe_pipe_capture(@cvs, '-q', 'status' ,$f));
|
||||
if (@status > 1) { warn 'Strange! cvs status returned more than one line?'};
|
||||
unless ($status[0] =~ m/Status: Up-to-date$/) {
|
||||
$dirty = 1;
|
||||
@ -194,7 +201,7 @@ print "Applying\n";
|
||||
print "Patch applied successfully. Adding new files and directories to CVS\n";
|
||||
my $dirtypatch = 0;
|
||||
foreach my $d (@dirs) {
|
||||
if (system('cvs','add',$d)) {
|
||||
if (system(@cvs,'add',$d)) {
|
||||
$dirtypatch = 1;
|
||||
warn "Failed to cvs add directory $d -- you may need to do it manually";
|
||||
}
|
||||
@ -202,9 +209,9 @@ foreach my $d (@dirs) {
|
||||
|
||||
foreach my $f (@afiles) {
|
||||
if (grep { $_ eq $f } @bfiles) {
|
||||
system('cvs', 'add','-kb',$f);
|
||||
system(@cvs, 'add','-kb',$f);
|
||||
} else {
|
||||
system('cvs', 'add', $f);
|
||||
system(@cvs, 'add', $f);
|
||||
}
|
||||
if ($?) {
|
||||
$dirtypatch = 1;
|
||||
@ -213,7 +220,7 @@ foreach my $f (@afiles) {
|
||||
}
|
||||
|
||||
foreach my $f (@dfiles) {
|
||||
system('cvs', 'rm', '-f', $f);
|
||||
system(@cvs, 'rm', '-f', $f);
|
||||
if ($?) {
|
||||
$dirtypatch = 1;
|
||||
warn "Failed to cvs rm -f $f -- you may need to do it manually";
|
||||
@ -223,7 +230,7 @@ foreach my $f (@dfiles) {
|
||||
print "Commit to CVS\n";
|
||||
print "Patch title (first comment line): $title\n";
|
||||
my @commitfiles = map { unless (m/\s/) { '\''.$_.'\''; } else { $_; }; } (@files);
|
||||
my $cmd = "cvs commit -F .msg @commitfiles";
|
||||
my $cmd = join(' ', @cvs)." commit -F .msg @commitfiles";
|
||||
|
||||
if ($dirtypatch) {
|
||||
print "NOTE: One or more hunks failed to apply cleanly.\n";
|
||||
@ -236,7 +243,7 @@ if ($dirtypatch) {
|
||||
|
||||
if ($opt_c) {
|
||||
print "Autocommit\n $cmd\n";
|
||||
print safe_pipe_capture('cvs', 'commit', '-F', '.msg', @files);
|
||||
print safe_pipe_capture(@cvs, 'commit', '-F', '.msg', @files);
|
||||
if ($?) {
|
||||
die "Exiting: The commit did not succeed";
|
||||
}
|
||||
|
@ -1171,6 +1171,21 @@ sub req_ci
|
||||
exit;
|
||||
}
|
||||
|
||||
# Check that this is allowed, just as we would with a receive-pack
|
||||
my @cmd = ( $ENV{GIT_DIR}.'hooks/update', "refs/heads/$state->{module}",
|
||||
$parenthash, $commithash );
|
||||
if( -x $cmd[0] ) {
|
||||
unless( system( @cmd ) == 0 )
|
||||
{
|
||||
$log->warn("Commit failed (update hook declined to update ref)");
|
||||
print "error 1 Commit failed (update hook declined)\n";
|
||||
close LOCKFILE;
|
||||
unlink($lockfile);
|
||||
chdir "/";
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
print LOCKFILE $commithash;
|
||||
|
||||
$updater->update();
|
||||
|
@ -243,6 +243,15 @@ then
|
||||
orig_head=$(git-rev-parse --verify HEAD 2>/dev/null)
|
||||
fi
|
||||
|
||||
# Allow --notags from remote.$1.tagopt
|
||||
case "$tags$no_tags" in
|
||||
'')
|
||||
case "$(git-config --get "remote.$1.tagopt")" in
|
||||
--no-tags)
|
||||
no_tags=t ;;
|
||||
esac
|
||||
esac
|
||||
|
||||
# If --tags (and later --heads or --all) is specified, then we are
|
||||
# not talking about defaults stored in Pull: line of remotes or
|
||||
# branches file, and just fetch those and refspecs explicitly given.
|
||||
|
1
git-gui/.gitignore
vendored
1
git-gui/.gitignore
vendored
@ -1,3 +1,4 @@
|
||||
CREDITS-FILE
|
||||
GIT-VERSION-FILE
|
||||
git-citool
|
||||
git-gui
|
||||
|
71
git-gui/CREDITS-GEN
Executable file
71
git-gui/CREDITS-GEN
Executable file
@ -0,0 +1,71 @@
|
||||
#!/bin/sh
|
||||
|
||||
CF=CREDITS-FILE
|
||||
tip=
|
||||
|
||||
tree_search ()
|
||||
{
|
||||
head=$1
|
||||
tree=$2
|
||||
for p in $(git rev-list --parents --max-count=1 $head 2>/dev/null)
|
||||
do
|
||||
test $tree = $(git rev-parse $p^{tree} 2>/dev/null) &&
|
||||
vn=$(git describe --abbrev=4 $p 2>/dev/null) &&
|
||||
case "$vn" in
|
||||
gitgui-[0-9]*) echo $p; break;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
generate_credits ()
|
||||
{
|
||||
tip=$1 &&
|
||||
rm -f "$2" &&
|
||||
git shortlog -n -s $tip | sed 's/: .*$//' >"$2" || exit
|
||||
}
|
||||
|
||||
# Always use the tarball credits file if found, just
|
||||
# in case we are somehow contained in a larger git
|
||||
# repository that doesn't actually track our state.
|
||||
# (At least one package manager is doing this.)
|
||||
#
|
||||
# We may be a subproject, so try looking for the merge
|
||||
# commit that supplied this directory content if we are
|
||||
# not at the toplevel. We probably will always be the
|
||||
# second parent in the commit, but we shouldn't rely on
|
||||
# that fact.
|
||||
#
|
||||
|
||||
credits_tmp=/var/tmp/gitgui-credits-$$
|
||||
trap 'rm -f "$credits_tmp"' 0
|
||||
|
||||
orig="$credits_tmp"
|
||||
|
||||
if test -f credits
|
||||
then
|
||||
orig=credits
|
||||
elif prefix="$(git rev-parse --show-prefix 2>/dev/null)" &&
|
||||
test -n "$prefix" &&
|
||||
head=$(git rev-list --max-count=1 HEAD -- . 2>/dev/null) &&
|
||||
tree=$(git rev-parse --verify "HEAD:$prefix" 2>/dev/null) &&
|
||||
tip=$(tree_search $head $tree) &&
|
||||
test -n "$tip"
|
||||
then
|
||||
generate_credits $tip "$orig" || exit
|
||||
elif tip="$(git rev-parse --verify HEAD 2>/dev/null)" &&
|
||||
test -n "$tip"
|
||||
then
|
||||
generate_credits $tip "$orig" || exit
|
||||
else
|
||||
echo "error: Cannot locate authorship information." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if test -f "$orig" && cmp -s "$orig" "$CF"
|
||||
then
|
||||
: noop
|
||||
else
|
||||
rm -f "$CF" &&
|
||||
cat "$orig" >"$CF"
|
||||
fi
|
||||
|
@ -20,6 +20,11 @@ tree_search ()
|
||||
done
|
||||
}
|
||||
|
||||
# Always use the tarball version file if found, just
|
||||
# in case we are somehow contained in a larger git
|
||||
# repository that doesn't actually track our state.
|
||||
# (At least one package manager is doing this.)
|
||||
#
|
||||
# We may be a subproject, so try looking for the merge
|
||||
# commit that supplied this directory content if we are
|
||||
# not at the toplevel. We probably will always be the
|
||||
@ -27,10 +32,13 @@ tree_search ()
|
||||
# that fact.
|
||||
#
|
||||
# If we are at the toplevel or the merge assumption fails
|
||||
# try looking for a gitgui-* tag, or fallback onto the
|
||||
# distributed version file.
|
||||
# try looking for a gitgui-* tag.
|
||||
|
||||
if prefix="$(git rev-parse --show-prefix 2>/dev/null)"
|
||||
if test -f version &&
|
||||
VN=$(cat version)
|
||||
then
|
||||
: happy
|
||||
elif prefix="$(git rev-parse --show-prefix 2>/dev/null)"
|
||||
test -n "$prefix" &&
|
||||
head=$(git rev-list --max-count=1 HEAD -- . 2>/dev/null) &&
|
||||
tree=$(git rev-parse --verify "HEAD:$prefix" 2>/dev/null) &&
|
||||
@ -48,9 +56,6 @@ elif VN=$(git describe --abbrev=4 HEAD 2>/dev/null) &&
|
||||
esac
|
||||
then
|
||||
VN=$(echo "$VN" | sed -e 's/^gitgui-//;s/-/./g');
|
||||
elif test -f version
|
||||
then
|
||||
VN=$(cat version) || VN="$DEF_VER"
|
||||
else
|
||||
VN="$DEF_VER"
|
||||
fi
|
||||
|
@ -4,9 +4,8 @@ GIT-VERSION-FILE: .FORCE-GIT-VERSION-FILE
|
||||
@$(SHELL_PATH) ./GIT-VERSION-GEN
|
||||
-include GIT-VERSION-FILE
|
||||
|
||||
SCRIPT_SH = git-gui.sh
|
||||
GITGUI_BUILT_INS = git-citool
|
||||
ALL_PROGRAMS = $(GITGUI_BUILT_INS) $(patsubst %.sh,%,$(SCRIPT_SH))
|
||||
ALL_PROGRAMS = git-gui $(GITGUI_BUILT_INS)
|
||||
|
||||
ifndef SHELL_PATH
|
||||
SHELL_PATH = /bin/sh
|
||||
@ -24,20 +23,24 @@ DESTDIR_SQ = $(subst ','\'',$(DESTDIR))
|
||||
gitexecdir_SQ = $(subst ','\'',$(gitexecdir))
|
||||
SHELL_PATH_SQ = $(subst ','\'',$(SHELL_PATH))
|
||||
|
||||
$(patsubst %.sh,%,$(SCRIPT_SH)) : % : %.sh
|
||||
git-gui: git-gui.sh GIT-VERSION-FILE CREDITS-FILE
|
||||
rm -f $@ $@+
|
||||
sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \
|
||||
sed -n \
|
||||
-e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \
|
||||
-e 's/@@GITGUI_VERSION@@/$(GITGUI_VERSION)/g' \
|
||||
-e '1,/^set gitgui_credits /p' \
|
||||
$@.sh >$@+
|
||||
cat CREDITS-FILE >>$@+
|
||||
sed -e '1,/^set gitgui_credits /d' $@.sh >>$@+
|
||||
chmod +x $@+
|
||||
mv $@+ $@
|
||||
|
||||
CREDITS-FILE: CREDITS-GEN .FORCE-CREDITS-FILE
|
||||
$(SHELL_PATH) ./CREDITS-GEN
|
||||
|
||||
$(GITGUI_BUILT_INS): git-gui
|
||||
rm -f $@ && ln git-gui $@
|
||||
|
||||
# These can record GITGUI_VERSION
|
||||
$(patsubst %.sh,%,$(SCRIPT_SH)): GIT-VERSION-FILE
|
||||
|
||||
all:: $(ALL_PROGRAMS)
|
||||
|
||||
install: all
|
||||
@ -45,12 +48,14 @@ install: all
|
||||
$(INSTALL) git-gui '$(DESTDIR_SQ)$(gitexecdir_SQ)'
|
||||
$(foreach p,$(GITGUI_BUILT_INS), rm -f '$(DESTDIR_SQ)$(gitexecdir_SQ)/$p' && ln '$(DESTDIR_SQ)$(gitexecdir_SQ)/git-gui' '$(DESTDIR_SQ)$(gitexecdir_SQ)/$p' ;)
|
||||
|
||||
dist-version:
|
||||
dist-version: CREDITS-FILE
|
||||
@mkdir -p $(TARDIR)
|
||||
@echo $(GITGUI_VERSION) > $(TARDIR)/version
|
||||
@cat CREDITS-FILE > $(TARDIR)/credits
|
||||
|
||||
clean::
|
||||
rm -f $(ALL_PROGRAMS) GIT-VERSION-FILE
|
||||
rm -f $(ALL_PROGRAMS) GIT-VERSION-FILE CREDITS-FILE
|
||||
|
||||
.PHONY: all install dist-version clean
|
||||
.PHONY: .FORCE-GIT-VERSION-FILE
|
||||
.PHONY: .FORCE-CREDITS-FILE
|
||||
|
44
git-gui/TODO
44
git-gui/TODO
@ -1,44 +0,0 @@
|
||||
Items outstanding:
|
||||
|
||||
* Add file to .gitignore or info/excludes.
|
||||
|
||||
* Populate the pull menu with local branches.
|
||||
|
||||
* Make use of the new default merge data stored in repo-config.
|
||||
|
||||
* Checkout a different local branch.
|
||||
|
||||
* Push any local branch to a remote branch.
|
||||
|
||||
* Merge any local branches through a real merge UI.
|
||||
|
||||
* Allow user to define keyboard shortcuts for frequently used fetch
|
||||
or merge operations. Or maybe just define a keyboard shortcut
|
||||
for default fetch/default merge of current branch is enough;
|
||||
but I do know a few users who merge a couple of common branches
|
||||
also into the same branch so one default isn't quite enough.
|
||||
|
||||
* Better organize fetch/push/pull console windows.
|
||||
|
||||
* Clone UI (to download a new repository).
|
||||
|
||||
* Remotes editor (for .git/config format only).
|
||||
|
||||
* Show a shortlog of the last couple of commits in the main window,
|
||||
to give the user warm fuzzy feelings that we have their data
|
||||
saved. Actually this may be the set of commits not yet in
|
||||
the upstream (aka default merge branch remote repository).
|
||||
|
||||
* GUI configuration editor for options listed in
|
||||
git.git/Documentation/config.txt. Ideally this would
|
||||
parse that file and generate the options dialog from
|
||||
the documentation itself, and include the help text
|
||||
from the documentation as part of the UI somehow.
|
||||
|
||||
Known bugs:
|
||||
|
||||
* git-gui sometimes just closes on Windows with no error message.
|
||||
I'm not sure what the problem is here. I suspect the wish
|
||||
process is just terminating due to a segfault or something,
|
||||
as the do_quit proc in git-gui doesn't run. It often seems to
|
||||
occur while writing a commit message in the buffer. Odd.
|
@ -4,7 +4,7 @@ exec wish "$0" -- "$@"
|
||||
|
||||
set appvers {@@GITGUI_VERSION@@}
|
||||
set copyright {
|
||||
Copyright © 2006, 2007 Shawn Pearce, Paul Mackerras.
|
||||
Copyright © 2006, 2007 Shawn Pearce, et. al.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -19,6 +19,9 @@ GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA}
|
||||
set gitgui_credits {
|
||||
Paul Mackerras
|
||||
}
|
||||
|
||||
######################################################################
|
||||
##
|
||||
@ -46,7 +49,7 @@ proc gitdir {args} {
|
||||
proc gitexec {args} {
|
||||
global _gitexec
|
||||
if {$_gitexec eq {}} {
|
||||
if {[catch {set _gitexec [exec git --exec-path]} err]} {
|
||||
if {[catch {set _gitexec [git --exec-path]} err]} {
|
||||
error "Git not installed?\n\n$err"
|
||||
}
|
||||
}
|
||||
@ -202,14 +205,14 @@ proc save_config {} {
|
||||
set value $global_config_new($name)
|
||||
if {$value ne $global_config($name)} {
|
||||
if {$value eq $default_config($name)} {
|
||||
catch {exec git config --global --unset $name}
|
||||
catch {git config --global --unset $name}
|
||||
} else {
|
||||
regsub -all "\[{}\]" $value {"} value
|
||||
exec git config --global $name $value
|
||||
git config --global $name $value
|
||||
}
|
||||
set global_config($name) $value
|
||||
if {$value eq $repo_config($name)} {
|
||||
catch {exec git config --unset $name}
|
||||
catch {git config --unset $name}
|
||||
set repo_config($name) $value
|
||||
}
|
||||
}
|
||||
@ -219,16 +222,24 @@ proc save_config {} {
|
||||
set value $repo_config_new($name)
|
||||
if {$value ne $repo_config($name)} {
|
||||
if {$value eq $global_config($name)} {
|
||||
catch {exec git config --unset $name}
|
||||
catch {git config --unset $name}
|
||||
} else {
|
||||
regsub -all "\[{}\]" $value {"} value
|
||||
exec git config $name $value
|
||||
git config $name $value
|
||||
}
|
||||
set repo_config($name) $value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
######################################################################
|
||||
##
|
||||
## handy utils
|
||||
|
||||
proc git {args} {
|
||||
return [eval exec git $args]
|
||||
}
|
||||
|
||||
proc error_popup {msg} {
|
||||
set title [appname]
|
||||
if {[reponame] ne {}} {
|
||||
@ -287,12 +298,44 @@ proc ask_popup {msg} {
|
||||
-message $msg]
|
||||
}
|
||||
|
||||
######################################################################
|
||||
##
|
||||
## version check
|
||||
|
||||
set req_maj 1
|
||||
set req_min 5
|
||||
|
||||
if {[catch {set v [git --version]} err]} {
|
||||
catch {wm withdraw .}
|
||||
error_popup "Cannot determine Git version:
|
||||
|
||||
$err
|
||||
|
||||
[appname] requires Git $req_maj.$req_min or later."
|
||||
exit 1
|
||||
}
|
||||
if {[regexp {^git version (\d+)\.(\d+)} $v _junk act_maj act_min]} {
|
||||
if {$act_maj < $req_maj
|
||||
|| ($act_maj == $req_maj && $act_min < $req_min)} {
|
||||
catch {wm withdraw .}
|
||||
error_popup "[appname] requires Git $req_maj.$req_min or later.
|
||||
|
||||
You are using $v."
|
||||
exit 1
|
||||
}
|
||||
} else {
|
||||
catch {wm withdraw .}
|
||||
error_popup "Cannot parse Git version string:\n\n$v"
|
||||
exit 1
|
||||
}
|
||||
unset -nocomplain v _junk act_maj act_min req_maj req_min
|
||||
|
||||
######################################################################
|
||||
##
|
||||
## repository setup
|
||||
|
||||
if { [catch {set _gitdir $env(GIT_DIR)}]
|
||||
&& [catch {set _gitdir [exec git rev-parse --git-dir]} err]} {
|
||||
&& [catch {set _gitdir [git rev-parse --git-dir]} err]} {
|
||||
catch {wm withdraw .}
|
||||
error_popup "Cannot find the git directory:\n\n$err"
|
||||
exit 1
|
||||
@ -319,6 +362,24 @@ set _reponame [lindex [file split \
|
||||
[file normalize [file dirname $_gitdir]]] \
|
||||
end]
|
||||
|
||||
######################################################################
|
||||
##
|
||||
## global init
|
||||
|
||||
set current_diff_path {}
|
||||
set current_diff_side {}
|
||||
set diff_actions [list]
|
||||
set ui_status_value {Initializing...}
|
||||
|
||||
set HEAD {}
|
||||
set PARENT {}
|
||||
set MERGE_HEAD [list]
|
||||
set commit_type {}
|
||||
set empty_tree {}
|
||||
set current_branch {}
|
||||
set current_diff_path {}
|
||||
set selected_commit_type new
|
||||
|
||||
######################################################################
|
||||
##
|
||||
## task management
|
||||
@ -365,7 +426,7 @@ proc repository_state {ctvar hdvar mhvar} {
|
||||
|
||||
set mh [list]
|
||||
|
||||
if {[catch {set current_branch [exec git symbolic-ref HEAD]}]} {
|
||||
if {[catch {set current_branch [git symbolic-ref HEAD]}]} {
|
||||
set current_branch {}
|
||||
} else {
|
||||
regsub ^refs/((heads|tags|remotes)/)? \
|
||||
@ -374,7 +435,7 @@ proc repository_state {ctvar hdvar mhvar} {
|
||||
current_branch
|
||||
}
|
||||
|
||||
if {[catch {set hd [exec git rev-parse --verify HEAD]}]} {
|
||||
if {[catch {set hd [git rev-parse --verify HEAD]}]} {
|
||||
set hd {}
|
||||
set ct initial
|
||||
return
|
||||
@ -402,7 +463,7 @@ proc PARENT {} {
|
||||
return $p
|
||||
}
|
||||
if {$empty_tree eq {}} {
|
||||
set empty_tree [exec git mktree << {}]
|
||||
set empty_tree [git mktree << {}]
|
||||
}
|
||||
return $empty_tree
|
||||
}
|
||||
@ -642,8 +703,9 @@ proc reshow_diff {} {
|
||||
global current_diff_path current_diff_side
|
||||
|
||||
set p $current_diff_path
|
||||
if {$p eq {}
|
||||
|| $current_diff_side eq {}
|
||||
if {$p eq {}} {
|
||||
# No diff is being shown.
|
||||
} elseif {$current_diff_side eq {}
|
||||
|| [catch {set s $file_states($p)}]
|
||||
|| [lsearch -sorted -exact $file_lists($current_diff_side) $p] == -1} {
|
||||
clear_diff
|
||||
@ -1042,7 +1104,7 @@ proc committer_ident {} {
|
||||
global GIT_COMMITTER_IDENT
|
||||
|
||||
if {$GIT_COMMITTER_IDENT eq {}} {
|
||||
if {[catch {set me [exec git var GIT_COMMITTER_IDENT]} err]} {
|
||||
if {[catch {set me [git var GIT_COMMITTER_IDENT]} err]} {
|
||||
error_popup "Unable to obtain your identity:\n\n$err"
|
||||
return {}
|
||||
}
|
||||
@ -1256,14 +1318,6 @@ proc commit_committree {fd_wt curHEAD msg} {
|
||||
return
|
||||
}
|
||||
|
||||
# -- Make sure our current branch exists.
|
||||
#
|
||||
if {$commit_type eq {initial}} {
|
||||
lappend all_heads $current_branch
|
||||
set all_heads [lsort -unique $all_heads]
|
||||
populate_branch_menu
|
||||
}
|
||||
|
||||
# -- Cleanup after ourselves.
|
||||
#
|
||||
catch {file delete $msg_p}
|
||||
@ -1275,7 +1329,7 @@ proc commit_committree {fd_wt curHEAD msg} {
|
||||
# -- Let rerere do its thing.
|
||||
#
|
||||
if {[file isdirectory [gitdir rr-cache]]} {
|
||||
catch {exec git rerere}
|
||||
catch {git rerere}
|
||||
}
|
||||
|
||||
# -- Run the post-commit hook.
|
||||
@ -1299,6 +1353,14 @@ proc commit_committree {fd_wt curHEAD msg} {
|
||||
|
||||
if {[is_enabled singlecommit]} do_quit
|
||||
|
||||
# -- Make sure our current branch exists.
|
||||
#
|
||||
if {$commit_type eq {initial}} {
|
||||
lappend all_heads $current_branch
|
||||
set all_heads [lsort -unique $all_heads]
|
||||
populate_branch_menu
|
||||
}
|
||||
|
||||
# -- Update in memory status
|
||||
#
|
||||
set selected_commit_type new
|
||||
@ -1876,11 +1938,24 @@ proc all_tracking_branches {} {
|
||||
return [lsort -unique $all_trackings]
|
||||
}
|
||||
|
||||
proc load_all_tags {} {
|
||||
set all_tags [list]
|
||||
set fd [open "| git for-each-ref --format=%(refname) refs/tags" r]
|
||||
while {[gets $fd line] > 0} {
|
||||
if {![regsub ^refs/tags/ $line {} name]} continue
|
||||
lappend all_tags $name
|
||||
}
|
||||
close $fd
|
||||
|
||||
return [lsort $all_tags]
|
||||
}
|
||||
|
||||
proc do_create_branch_action {w} {
|
||||
global all_heads null_sha1 repo_config
|
||||
global create_branch_checkout create_branch_revtype
|
||||
global create_branch_head create_branch_trackinghead
|
||||
global create_branch_name create_branch_revexp
|
||||
global create_branch_tag
|
||||
|
||||
set newbranch $create_branch_name
|
||||
if {$newbranch eq {}
|
||||
@ -1894,7 +1969,7 @@ proc do_create_branch_action {w} {
|
||||
focus $w.desc.name_t
|
||||
return
|
||||
}
|
||||
if {![catch {exec git show-ref --verify -- "refs/heads/$newbranch"}]} {
|
||||
if {![catch {git show-ref --verify -- "refs/heads/$newbranch"}]} {
|
||||
tk_messageBox \
|
||||
-icon error \
|
||||
-type ok \
|
||||
@ -1904,7 +1979,7 @@ proc do_create_branch_action {w} {
|
||||
focus $w.desc.name_t
|
||||
return
|
||||
}
|
||||
if {[catch {exec git check-ref-format "heads/$newbranch"}]} {
|
||||
if {[catch {git check-ref-format "heads/$newbranch"}]} {
|
||||
tk_messageBox \
|
||||
-icon error \
|
||||
-type ok \
|
||||
@ -1919,9 +1994,10 @@ proc do_create_branch_action {w} {
|
||||
switch -- $create_branch_revtype {
|
||||
head {set rev $create_branch_head}
|
||||
tracking {set rev $create_branch_trackinghead}
|
||||
tag {set rev $create_branch_tag}
|
||||
expression {set rev $create_branch_revexp}
|
||||
}
|
||||
if {[catch {set cmt [exec git rev-parse --verify "${rev}^0"]}]} {
|
||||
if {[catch {set cmt [git rev-parse --verify "${rev}^0"]}]} {
|
||||
tk_messageBox \
|
||||
-icon error \
|
||||
-type ok \
|
||||
@ -1964,6 +2040,8 @@ trace add variable create_branch_head write \
|
||||
[list radio_selector create_branch_revtype head]
|
||||
trace add variable create_branch_trackinghead write \
|
||||
[list radio_selector create_branch_revtype tracking]
|
||||
trace add variable create_branch_tag write \
|
||||
[list radio_selector create_branch_revtype tag]
|
||||
|
||||
trace add variable delete_branch_head write \
|
||||
[list radio_selector delete_branch_checktype head]
|
||||
@ -1975,6 +2053,7 @@ proc do_create_branch {} {
|
||||
global create_branch_checkout create_branch_revtype
|
||||
global create_branch_head create_branch_trackinghead
|
||||
global create_branch_name create_branch_revexp
|
||||
global create_branch_tag
|
||||
|
||||
set w .branch_editor
|
||||
toplevel $w
|
||||
@ -2038,6 +2117,19 @@ proc do_create_branch {} {
|
||||
$all_trackings
|
||||
grid $w.from.tracking_r $w.from.tracking_m -sticky w
|
||||
}
|
||||
set all_tags [load_all_tags]
|
||||
if {$all_tags ne {}} {
|
||||
set create_branch_tag [lindex $all_tags 0]
|
||||
radiobutton $w.from.tag_r \
|
||||
-text {Tag:} \
|
||||
-value tag \
|
||||
-variable create_branch_revtype \
|
||||
-font font_ui
|
||||
eval tk_optionMenu $w.from.tag_m \
|
||||
create_branch_tag \
|
||||
$all_tags
|
||||
grid $w.from.tag_r $w.from.tag_m -sticky w
|
||||
}
|
||||
radiobutton $w.from.exp_r \
|
||||
-text {Revision Expression:} \
|
||||
-value expression \
|
||||
@ -2100,7 +2192,7 @@ proc do_delete_branch_action {w} {
|
||||
}
|
||||
if {$check_rev eq {:none}} {
|
||||
set check_cmt {}
|
||||
} elseif {[catch {set check_cmt [exec git rev-parse --verify "${check_rev}^0"]}]} {
|
||||
} elseif {[catch {set check_cmt [git rev-parse --verify "${check_rev}^0"]}]} {
|
||||
tk_messageBox \
|
||||
-icon error \
|
||||
-type ok \
|
||||
@ -2114,10 +2206,10 @@ proc do_delete_branch_action {w} {
|
||||
set not_merged [list]
|
||||
foreach i [$w.list.l curselection] {
|
||||
set b [$w.list.l get $i]
|
||||
if {[catch {set o [exec git rev-parse --verify $b]}]} continue
|
||||
if {[catch {set o [git rev-parse --verify $b]}]} continue
|
||||
if {$check_cmt ne {}} {
|
||||
if {$b eq $check_rev} continue
|
||||
if {[catch {set m [exec git merge-base $o $check_cmt]}]} continue
|
||||
if {[catch {set m [git merge-base $o $check_cmt]}]} continue
|
||||
if {$o ne $m} {
|
||||
lappend not_merged $b
|
||||
continue
|
||||
@ -2155,7 +2247,7 @@ Delete the selected branches?}
|
||||
foreach i $to_delete {
|
||||
set b [lindex $i 0]
|
||||
set o [lindex $i 1]
|
||||
if {[catch {exec git update-ref -d "refs/heads/$b" $o} err]} {
|
||||
if {[catch {git update-ref -d "refs/heads/$b" $o} err]} {
|
||||
append failed " - $b: $err\n"
|
||||
} else {
|
||||
set x [lsearch -sorted -exact $all_heads $b]
|
||||
@ -2366,7 +2458,7 @@ Staying on branch '$current_branch'."
|
||||
# here, it Just Works(tm). If it doesn't we are in some really ugly
|
||||
# state that is difficult to recover from within git-gui.
|
||||
#
|
||||
if {[catch {exec git symbolic-ref HEAD "refs/heads/$new_branch"} err]} {
|
||||
if {[catch {git symbolic-ref HEAD "refs/heads/$new_branch"} err]} {
|
||||
error_popup "Failed to set current branch.
|
||||
|
||||
This working directory is only partially switched.
|
||||
@ -2876,14 +2968,16 @@ proc do_local_merge {} {
|
||||
pack $w.source -fill both -expand 1 -pady 5 -padx 5
|
||||
|
||||
set cmd [list git for-each-ref]
|
||||
lappend cmd {--format=%(objectname) %(refname)}
|
||||
lappend cmd {--format=%(objectname) %(*objectname) %(refname)}
|
||||
lappend cmd refs/heads
|
||||
lappend cmd refs/remotes
|
||||
lappend cmd refs/tags
|
||||
set fr_fd [open "| $cmd" r]
|
||||
fconfigure $fr_fd -translation binary
|
||||
while {[gets $fr_fd line] > 0} {
|
||||
set line [split $line { }]
|
||||
set sha1([lindex $line 0]) [lindex $line 1]
|
||||
set sha1([lindex $line 0]) [lindex $line 2]
|
||||
set sha1([lindex $line 1]) [lindex $line 2]
|
||||
}
|
||||
close $fr_fd
|
||||
|
||||
@ -2891,7 +2985,7 @@ proc do_local_merge {} {
|
||||
set fr_fd [open "| git rev-list --all --not HEAD"]
|
||||
while {[gets $fr_fd line] > 0} {
|
||||
if {[catch {set ref $sha1($line)}]} continue
|
||||
regsub ^refs/(heads|remotes)/ $ref {} ref
|
||||
regsub ^refs/(heads|remotes|tags)/ $ref {} ref
|
||||
lappend to_show $ref
|
||||
}
|
||||
close $fr_fd
|
||||
@ -2972,7 +3066,14 @@ proc new_browser {commit} {
|
||||
global next_browser_id cursor_ptr M1B
|
||||
global browser_commit browser_status browser_stack browser_path browser_busy
|
||||
|
||||
set w .browser[incr next_browser_id]
|
||||
if {[winfo ismapped .]} {
|
||||
set w .browser[incr next_browser_id]
|
||||
set tl $w
|
||||
toplevel $w
|
||||
} else {
|
||||
set w {}
|
||||
set tl .
|
||||
}
|
||||
set w_list $w.list.l
|
||||
set browser_commit($w_list) $commit
|
||||
set browser_status($w_list) {Starting...}
|
||||
@ -2980,7 +3081,6 @@ proc new_browser {commit} {
|
||||
set browser_path($w_list) $browser_commit($w_list):
|
||||
set browser_busy($w_list) 1
|
||||
|
||||
toplevel $w
|
||||
label $w.path -textvariable browser_path($w_list) \
|
||||
-anchor w \
|
||||
-justify left \
|
||||
@ -3030,8 +3130,8 @@ proc new_browser {commit} {
|
||||
bind $w_list <Left> break
|
||||
bind $w_list <Right> break
|
||||
|
||||
bind $w <Visibility> "focus $w"
|
||||
bind $w <Destroy> "
|
||||
bind $tl <Visibility> "focus $w"
|
||||
bind $tl <Destroy> "
|
||||
array unset browser_buffer $w_list
|
||||
array unset browser_files $w_list
|
||||
array unset browser_status $w_list
|
||||
@ -3040,7 +3140,7 @@ proc new_browser {commit} {
|
||||
array unset browser_commit $w_list
|
||||
array unset browser_busy $w_list
|
||||
"
|
||||
wm title $w "[appname] ([reponame]): File Browser"
|
||||
wm title $tl "[appname] ([reponame]): File Browser"
|
||||
ls_tree $w_list $browser_commit($w_list) {}
|
||||
}
|
||||
|
||||
@ -4161,7 +4261,7 @@ proc do_quit {} {
|
||||
set rc_geometry {}
|
||||
}
|
||||
if {$cfg_geometry ne $rc_geometry} {
|
||||
catch {exec git config gui.geometry $cfg_geometry}
|
||||
catch {git config gui.geometry $cfg_geometry}
|
||||
}
|
||||
}
|
||||
|
||||
@ -4380,6 +4480,61 @@ proc do_commit {} {
|
||||
commit_tree
|
||||
}
|
||||
|
||||
proc do_credits {} {
|
||||
global gitgui_credits
|
||||
|
||||
set w .credits_dialog
|
||||
|
||||
toplevel $w
|
||||
wm geometry $w "+[winfo rootx .]+[winfo rooty .]"
|
||||
|
||||
label $w.header -text {git-gui Contributors} -font font_uibold
|
||||
pack $w.header -side top -fill x
|
||||
|
||||
frame $w.buttons
|
||||
button $w.buttons.close -text {Close} \
|
||||
-font font_ui \
|
||||
-command [list destroy $w]
|
||||
pack $w.buttons.close -side right
|
||||
pack $w.buttons -side bottom -fill x -pady 10 -padx 10
|
||||
|
||||
frame $w.credits
|
||||
text $w.credits.t \
|
||||
-background [$w.header cget -background] \
|
||||
-yscrollcommand [list $w.credits.sby set] \
|
||||
-width 20 \
|
||||
-height 10 \
|
||||
-wrap none \
|
||||
-borderwidth 1 \
|
||||
-relief solid \
|
||||
-padx 5 -pady 5 \
|
||||
-font font_ui
|
||||
scrollbar $w.credits.sby -command [list $w.credits.t yview]
|
||||
pack $w.credits.sby -side right -fill y
|
||||
pack $w.credits.t -fill both -expand 1
|
||||
pack $w.credits -side top -fill both -expand 1 -padx 5 -pady 5
|
||||
|
||||
label $w.desc \
|
||||
-text "All portions are copyrighted by their respective authors
|
||||
and are distributed under the GNU General Public License." \
|
||||
-padx 5 -pady 5 \
|
||||
-justify left \
|
||||
-anchor w \
|
||||
-borderwidth 1 \
|
||||
-relief solid \
|
||||
-font font_ui
|
||||
pack $w.desc -side top -fill x -padx 5 -pady 5
|
||||
|
||||
$w.credits.t insert end "[string trim $gitgui_credits]\n"
|
||||
$w.credits.t conf -state disabled
|
||||
$w.credits.t see 1.0
|
||||
|
||||
bind $w <Visibility> "grab $w; focus $w"
|
||||
bind $w <Key-Escape> [list destroy $w]
|
||||
wm title $w [$w.header cget -text]
|
||||
tkwait window $w
|
||||
}
|
||||
|
||||
proc do_about {} {
|
||||
global appvers copyright
|
||||
global tcl_patchLevel tk_patchLevel
|
||||
@ -4396,11 +4551,15 @@ proc do_about {} {
|
||||
button $w.buttons.close -text {Close} \
|
||||
-font font_ui \
|
||||
-command [list destroy $w]
|
||||
button $w.buttons.credits -text {Contributors} \
|
||||
-font font_ui \
|
||||
-command do_credits
|
||||
pack $w.buttons.credits -side left
|
||||
pack $w.buttons.close -side right
|
||||
pack $w.buttons -side bottom -fill x -pady 10 -padx 10
|
||||
|
||||
label $w.desc \
|
||||
-text "[appname] - a commit creation tool for Git.
|
||||
-text "git-gui - a graphical user interface for Git.
|
||||
$copyright" \
|
||||
-padx 5 -pady 5 \
|
||||
-justify left \
|
||||
@ -4411,8 +4570,8 @@ $copyright" \
|
||||
pack $w.desc -side top -fill x -padx 5 -pady 5
|
||||
|
||||
set v {}
|
||||
append v "[appname] version $appvers\n"
|
||||
append v "[exec git version]\n"
|
||||
append v "git-gui version $appvers\n"
|
||||
append v "[git version]\n"
|
||||
append v "\n"
|
||||
if {$tcl_patchLevel eq $tk_patchLevel} {
|
||||
append v "Tcl/Tk version $tcl_patchLevel"
|
||||
@ -4471,7 +4630,7 @@ proc do_options {} {
|
||||
toplevel $w
|
||||
wm geometry $w "+[winfo rootx .]+[winfo rooty .]"
|
||||
|
||||
label $w.header -text "[appname] Options" \
|
||||
label $w.header -text "Options" \
|
||||
-font font_uibold
|
||||
pack $w.header -side top -fill x
|
||||
|
||||
@ -4945,6 +5104,9 @@ enable_option branch
|
||||
enable_option transport
|
||||
|
||||
switch -- $subcommand {
|
||||
--version -
|
||||
version -
|
||||
browser -
|
||||
blame {
|
||||
disable_option multicommit
|
||||
disable_option branch
|
||||
@ -5177,7 +5339,7 @@ if {[is_MacOSX]} {
|
||||
.mbar.apple add command -label "About [appname]" \
|
||||
-command do_about \
|
||||
-font font_ui
|
||||
.mbar.apple add command -label "[appname] Options..." \
|
||||
.mbar.apple add command -label "Options..." \
|
||||
-command do_options \
|
||||
-font font_ui
|
||||
} else {
|
||||
@ -5236,7 +5398,7 @@ set doc_path [file dirname [gitexec]]
|
||||
set doc_path [file join $doc_path Documentation index.html]
|
||||
|
||||
if {[is_Cygwin]} {
|
||||
set doc_path [exec cygpath --windows $doc_path]
|
||||
set doc_path [exec cygpath --mixed $doc_path]
|
||||
}
|
||||
|
||||
if {$browser eq {}} {
|
||||
@ -5280,6 +5442,20 @@ bind all <$M1B-Key-W> {destroy [winfo toplevel %W]}
|
||||
# -- Not a normal commit type invocation? Do that instead!
|
||||
#
|
||||
switch -- $subcommand {
|
||||
--version -
|
||||
version {
|
||||
puts "git-gui version $appvers"
|
||||
exit
|
||||
}
|
||||
browser {
|
||||
if {[llength $argv] != 1} {
|
||||
puts stderr "usage: $argv0 browser commit"
|
||||
exit 1
|
||||
}
|
||||
set current_branch [lindex $argv 0]
|
||||
new_browser $current_branch
|
||||
return
|
||||
}
|
||||
blame {
|
||||
if {[llength $argv] != 2} {
|
||||
puts stderr "usage: $argv0 blame commit path"
|
||||
@ -5302,7 +5478,7 @@ gui {
|
||||
# fall through to setup UI for commits
|
||||
}
|
||||
default {
|
||||
puts stderr "usage: $argv0 \[{blame|citool}\]"
|
||||
puts stderr "usage: $argv0 \[{blame|browser|citool}\]"
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
@ -5552,9 +5728,6 @@ bind_button3 $ui_comm "tk_popup $ctxm %X %Y"
|
||||
|
||||
# -- Diff Header
|
||||
#
|
||||
set current_diff_path {}
|
||||
set current_diff_side {}
|
||||
set diff_actions [list]
|
||||
proc trace_current_diff_path {varname args} {
|
||||
global current_diff_path diff_actions file_states
|
||||
if {$current_diff_path eq {}} {
|
||||
@ -5747,7 +5920,6 @@ unset ui_diff_applyhunk
|
||||
|
||||
# -- Status Bar
|
||||
#
|
||||
set ui_status_value {Initializing...}
|
||||
label .status -textvariable ui_status_value \
|
||||
-anchor w \
|
||||
-justify left \
|
||||
@ -5821,15 +5993,6 @@ unset i
|
||||
set file_lists($ui_index) [list]
|
||||
set file_lists($ui_workdir) [list]
|
||||
|
||||
set HEAD {}
|
||||
set PARENT {}
|
||||
set MERGE_HEAD [list]
|
||||
set commit_type {}
|
||||
set empty_tree {}
|
||||
set current_branch {}
|
||||
set current_diff_path {}
|
||||
set selected_commit_type new
|
||||
|
||||
wm title . "[appname] ([file normalize [file dirname [gitdir]]])"
|
||||
focus -force $ui_comm
|
||||
|
||||
@ -5904,7 +6067,7 @@ if {[is_enabled transport]} {
|
||||
if {[is_enabled multicommit]} {
|
||||
set object_limit 2000
|
||||
if {[is_Windows]} {set object_limit 200}
|
||||
regexp {^([0-9]+) objects,} [exec git count-objects] _junk objects_current
|
||||
regexp {^([0-9]+) objects,} [git count-objects] _junk objects_current
|
||||
if {$objects_current >= $object_limit} {
|
||||
if {[ask_popup \
|
||||
"This repository currently has $objects_current loose objects.
|
||||
|
@ -67,7 +67,7 @@ sub list_remote {
|
||||
$git->command(qw(config --get-regexp), '^remote\.');
|
||||
};
|
||||
for (@remotes) {
|
||||
if (/^remote\.([^.]*)\.(\S*)\s+(.*)$/) {
|
||||
if (/^remote\.(\S+?)\.([^.\s]+)\s+(.*)$/) {
|
||||
add_remote_config(\%seen, $1, $2, $3);
|
||||
}
|
||||
}
|
||||
@ -274,6 +274,31 @@ sub add_remote {
|
||||
}
|
||||
}
|
||||
|
||||
sub update_remote {
|
||||
my ($name) = @_;
|
||||
|
||||
my $conf = $git->config("remotes." . $name);
|
||||
if (defined($conf)) {
|
||||
@remotes = split(' ', $conf);
|
||||
} elsif ($name eq 'default') {
|
||||
undef @remotes;
|
||||
for (sort keys %$remote) {
|
||||
my $do_fetch = $git->config_boolean("remote." . $_ .
|
||||
".skipDefaultUpdate");
|
||||
if (!defined($do_fetch) || $do_fetch ne "true") {
|
||||
push @remotes, $_;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
print STDERR "Remote group $name does not exists.\n";
|
||||
exit(1);
|
||||
}
|
||||
for (@remotes) {
|
||||
print "Updating $_\n";
|
||||
$git->command('fetch', "$_");
|
||||
}
|
||||
}
|
||||
|
||||
sub add_usage {
|
||||
print STDERR "Usage: git remote add [-f] [-t track]* [-m master] <name> <url>\n";
|
||||
exit(1);
|
||||
@ -303,6 +328,15 @@ elsif ($ARGV[0] eq 'show') {
|
||||
show_remote($ARGV[$i], $ls_remote);
|
||||
}
|
||||
}
|
||||
elsif ($ARGV[0] eq 'update') {
|
||||
if (@ARGV <= 1) {
|
||||
update_remote("default");
|
||||
exit(1);
|
||||
}
|
||||
for ($i = 1; $i < @ARGV; $i++) {
|
||||
update_remote($ARGV[$i]);
|
||||
}
|
||||
}
|
||||
elsif ($ARGV[0] eq 'prune') {
|
||||
my $ls_remote = 1;
|
||||
my $i;
|
||||
@ -360,5 +394,6 @@ else {
|
||||
print STDERR " git remote add <name> <url>\n";
|
||||
print STDERR " git remote show <name>\n";
|
||||
print STDERR " git remote prune <name>\n";
|
||||
print STDERR " git remote update [group]\n";
|
||||
exit(1);
|
||||
}
|
||||
|
5174
git-svn.perl
5174
git-svn.perl
File diff suppressed because it is too large
Load Diff
12
git.c
12
git.c
@ -48,7 +48,7 @@ static int handle_options(const char*** argv, int* argc)
|
||||
/*
|
||||
* Check remaining flags.
|
||||
*/
|
||||
if (!strncmp(cmd, "--exec-path", 11)) {
|
||||
if (!prefixcmp(cmd, "--exec-path")) {
|
||||
cmd += 11;
|
||||
if (*cmd == '=')
|
||||
git_set_exec_path(cmd + 1);
|
||||
@ -66,7 +66,7 @@ static int handle_options(const char*** argv, int* argc)
|
||||
setenv(GIT_DIR_ENVIRONMENT, (*argv)[1], 1);
|
||||
(*argv)++;
|
||||
(*argc)--;
|
||||
} else if (!strncmp(cmd, "--git-dir=", 10)) {
|
||||
} else if (!prefixcmp(cmd, "--git-dir=")) {
|
||||
setenv(GIT_DIR_ENVIRONMENT, cmd + 10, 1);
|
||||
} else if (!strcmp(cmd, "--bare")) {
|
||||
static char git_dir[PATH_MAX+1];
|
||||
@ -88,7 +88,7 @@ static char *alias_string;
|
||||
|
||||
static int git_alias_config(const char *var, const char *value)
|
||||
{
|
||||
if (!strncmp(var, "alias.", 6) && !strcmp(var + 6, alias_command)) {
|
||||
if (!prefixcmp(var, "alias.") && !strcmp(var + 6, alias_command)) {
|
||||
alias_string = xstrdup(value);
|
||||
}
|
||||
return 0;
|
||||
@ -247,7 +247,7 @@ static void handle_internal_command(int argc, const char **argv, char **envp)
|
||||
{ "fsck", cmd_fsck, RUN_SETUP },
|
||||
{ "fsck-objects", cmd_fsck, RUN_SETUP },
|
||||
{ "get-tar-commit-id", cmd_get_tar_commit_id },
|
||||
{ "grep", cmd_grep, RUN_SETUP },
|
||||
{ "grep", cmd_grep, RUN_SETUP | USE_PAGER },
|
||||
{ "help", cmd_help },
|
||||
{ "init", cmd_init_db },
|
||||
{ "init-db", cmd_init_db },
|
||||
@ -348,7 +348,7 @@ int main(int argc, const char **argv, char **envp)
|
||||
* So we just directly call the internal command handler, and
|
||||
* die if that one cannot handle it.
|
||||
*/
|
||||
if (!strncmp(cmd, "git-", 4)) {
|
||||
if (!prefixcmp(cmd, "git-")) {
|
||||
cmd += 4;
|
||||
argv[0] = cmd;
|
||||
handle_internal_command(argc, argv, envp);
|
||||
@ -360,7 +360,7 @@ int main(int argc, const char **argv, char **envp)
|
||||
argc--;
|
||||
handle_options(&argv, &argc);
|
||||
if (argc > 0) {
|
||||
if (!strncmp(argv[0], "--", 2))
|
||||
if (!prefixcmp(argv[0], "--"))
|
||||
argv[0] += 2;
|
||||
} else {
|
||||
/* Default command: "help" */
|
||||
|
4
help.c
4
help.c
@ -130,7 +130,7 @@ static void list_commands(const char *exec_path, const char *pattern)
|
||||
struct stat st;
|
||||
int entlen;
|
||||
|
||||
if (strncmp(de->d_name, "git-", 4))
|
||||
if (prefixcmp(de->d_name, "git-"))
|
||||
continue;
|
||||
strcpy(path+dirlen, de->d_name);
|
||||
if (stat(path, &st) || /* stat, not lstat */
|
||||
@ -179,7 +179,7 @@ static void show_man_page(const char *git_cmd)
|
||||
{
|
||||
const char *page;
|
||||
|
||||
if (!strncmp(git_cmd, "git", 3))
|
||||
if (!prefixcmp(git_cmd, "git"))
|
||||
page = git_cmd;
|
||||
else {
|
||||
int page_len = strlen(git_cmd) + 4;
|
||||
|
@ -717,8 +717,8 @@ static int fetch_indices(struct alt_base *repo)
|
||||
case 'P':
|
||||
i++;
|
||||
if (i + 52 <= buffer.posn &&
|
||||
!strncmp(data + i, " pack-", 6) &&
|
||||
!strncmp(data + i + 46, ".pack\n", 6)) {
|
||||
!prefixcmp(data + i, " pack-") &&
|
||||
!prefixcmp(data + i + 46, ".pack\n")) {
|
||||
get_sha1_hex(data + i + 6, sha1);
|
||||
setup_index(repo, sha1);
|
||||
i += 51;
|
||||
|
10
http-push.c
10
http-push.c
@ -1060,8 +1060,8 @@ static int fetch_indices(void)
|
||||
case 'P':
|
||||
i++;
|
||||
if (i + 52 < buffer.posn &&
|
||||
!strncmp(data + i, " pack-", 6) &&
|
||||
!strncmp(data + i + 46, ".pack\n", 6)) {
|
||||
!prefixcmp(data + i, " pack-") &&
|
||||
!prefixcmp(data + i + 46, ".pack\n")) {
|
||||
get_sha1_hex(data + i + 6, sha1);
|
||||
setup_index(sha1);
|
||||
i += 51;
|
||||
@ -1206,11 +1206,11 @@ static void handle_new_lock_ctx(struct xml_ctx *ctx, int tag_closed)
|
||||
lock->owner = xmalloc(strlen(ctx->cdata) + 1);
|
||||
strcpy(lock->owner, ctx->cdata);
|
||||
} else if (!strcmp(ctx->name, DAV_ACTIVELOCK_TIMEOUT)) {
|
||||
if (!strncmp(ctx->cdata, "Second-", 7))
|
||||
if (!prefixcmp(ctx->cdata, "Second-"))
|
||||
lock->timeout =
|
||||
strtol(ctx->cdata + 7, NULL, 10);
|
||||
} else if (!strcmp(ctx->name, DAV_ACTIVELOCK_TOKEN)) {
|
||||
if (!strncmp(ctx->cdata, "opaquelocktoken:", 16)) {
|
||||
if (!prefixcmp(ctx->cdata, "opaquelocktoken:")) {
|
||||
lock->token = xmalloc(strlen(ctx->cdata) - 15);
|
||||
strcpy(lock->token, ctx->cdata + 16);
|
||||
}
|
||||
@ -2168,7 +2168,7 @@ static void fetch_symref(const char *path, char **symref, unsigned char *sha1)
|
||||
return;
|
||||
|
||||
/* If it's a symref, set the refname; otherwise try for a sha1 */
|
||||
if (!strncmp((char *)buffer.buffer, "ref: ", 5)) {
|
||||
if (!prefixcmp((char *)buffer.buffer, "ref: ")) {
|
||||
*symref = xmalloc(buffer.posn - 5);
|
||||
strlcpy(*symref, (char *)buffer.buffer + 5, buffer.posn - 5);
|
||||
} else {
|
||||
|
@ -1192,7 +1192,7 @@ count_messages( msg_data_t *msg )
|
||||
char *p = msg->data;
|
||||
|
||||
while (1) {
|
||||
if (!strncmp( "From ", p, 5 )) {
|
||||
if (!prefixcmp(p, "From ")) {
|
||||
count++;
|
||||
p += 5;
|
||||
}
|
||||
@ -1216,7 +1216,7 @@ split_msg( msg_data_t *all_msgs, msg_data_t *msg, int *ofs )
|
||||
data = &all_msgs->data[ *ofs ];
|
||||
msg->len = all_msgs->len - *ofs;
|
||||
|
||||
if (msg->len < 5 || strncmp( data, "From ", 5 ))
|
||||
if (msg->len < 5 || prefixcmp(data, "From "))
|
||||
return 0;
|
||||
|
||||
p = strchr( data, '\n' );
|
||||
@ -1267,12 +1267,12 @@ git_imap_config(const char *key, const char *val)
|
||||
imap_folder = xstrdup( val );
|
||||
} else if (!strcmp( "host", key )) {
|
||||
{
|
||||
if (!strncmp( "imap:", val, 5 ))
|
||||
if (!prefixcmp(val, "imap:"))
|
||||
val += 5;
|
||||
if (!server.port)
|
||||
server.port = 143;
|
||||
}
|
||||
if (!strncmp( "//", val, 2 ))
|
||||
if (!prefixcmp(val, "//"))
|
||||
val += 2;
|
||||
server.host = xstrdup( val );
|
||||
}
|
||||
|
@ -849,9 +849,9 @@ int main(int argc, char **argv)
|
||||
fix_thin_pack = 1;
|
||||
} else if (!strcmp(arg, "--keep")) {
|
||||
keep_msg = "";
|
||||
} else if (!strncmp(arg, "--keep=", 7)) {
|
||||
} else if (!prefixcmp(arg, "--keep=")) {
|
||||
keep_msg = arg + 7;
|
||||
} else if (!strncmp(arg, "--pack_header=", 14)) {
|
||||
} else if (!prefixcmp(arg, "--pack_header=")) {
|
||||
struct pack_header *hdr;
|
||||
char *c;
|
||||
|
||||
|
@ -60,7 +60,7 @@ static int merge_entry(int pos, const char *path)
|
||||
break;
|
||||
found++;
|
||||
strcpy(hexbuf[stage], sha1_to_hex(ce->sha1));
|
||||
sprintf(ownbuf[stage], "%o", ntohl(ce->ce_mode) & (~S_IFMT));
|
||||
sprintf(ownbuf[stage], "%o", ntohl(ce->ce_mode));
|
||||
arguments[stage] = hexbuf[stage];
|
||||
arguments[stage + 4] = ownbuf[stage];
|
||||
} while (++pos < active_nr);
|
||||
|
@ -589,7 +589,7 @@ static void update_file_flags(const unsigned char *sha,
|
||||
memcpy(lnk, buf, size);
|
||||
lnk[size] = '\0';
|
||||
mkdir_p(path, 0777);
|
||||
unlink(lnk);
|
||||
unlink(path);
|
||||
symlink(lnk, path);
|
||||
} else
|
||||
die("do not know what to do with %06o %s '%s'",
|
||||
|
@ -35,11 +35,11 @@ int main(int argc, char **argv)
|
||||
char *arg = argv[i];
|
||||
|
||||
if (*arg == '-') {
|
||||
if (!strncmp("--upload-pack=", arg, 14)) {
|
||||
if (!prefixcmp(arg, "--upload-pack=")) {
|
||||
uploadpack = arg + 14;
|
||||
continue;
|
||||
}
|
||||
if (!strncmp("--exec=", arg, 7)) {
|
||||
if (!prefixcmp(arg, "--exec=")) {
|
||||
uploadpack = arg + 7;
|
||||
continue;
|
||||
}
|
||||
|
30
perl/Git.pm
30
perl/Git.pm
@ -516,6 +516,36 @@ sub config {
|
||||
}
|
||||
|
||||
|
||||
=item config_boolean ( VARIABLE )
|
||||
|
||||
Retrieve the boolean configuration C<VARIABLE>.
|
||||
|
||||
Must be called on a repository instance.
|
||||
|
||||
This currently wraps command('config') so it is not so fast.
|
||||
|
||||
=cut
|
||||
|
||||
sub config_boolean {
|
||||
my ($self, $var) = @_;
|
||||
$self->repo_path()
|
||||
or throw Error::Simple("not a repository");
|
||||
|
||||
try {
|
||||
return $self->command_oneline('config', '--bool', '--get',
|
||||
$var);
|
||||
} catch Git::Error::Command with {
|
||||
my $E = shift;
|
||||
if ($E->value() == 1) {
|
||||
# Key not found.
|
||||
return undef;
|
||||
} else {
|
||||
throw $E;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
=item ident ( TYPE | IDENTSTR )
|
||||
|
||||
=item ident_person ( TYPE | IDENTSTR | IDENTARRAY )
|
||||
|
@ -109,7 +109,7 @@ static int update(struct command *cmd)
|
||||
struct ref_lock *lock;
|
||||
|
||||
cmd->error_string = NULL;
|
||||
if (!strncmp(name, "refs/", 5) && check_ref_format(name + 5)) {
|
||||
if (!prefixcmp(name, "refs/") && check_ref_format(name + 5)) {
|
||||
cmd->error_string = "funny refname";
|
||||
return error("refusing to create funny ref '%s' locally",
|
||||
name);
|
||||
@ -125,7 +125,7 @@ static int update(struct command *cmd)
|
||||
}
|
||||
if (deny_non_fast_forwards && !is_null_sha1(new_sha1) &&
|
||||
!is_null_sha1(old_sha1) &&
|
||||
!strncmp(name, "refs/heads/", 11)) {
|
||||
!prefixcmp(name, "refs/heads/")) {
|
||||
struct commit *old_commit, *new_commit;
|
||||
struct commit_list *bases, *ent;
|
||||
|
||||
|
8
refs.c
8
refs.c
@ -828,8 +828,8 @@ int rename_ref(const char *oldref, const char *newref, const char *logmsg)
|
||||
goto rollback;
|
||||
}
|
||||
|
||||
if (!strncmp(oldref, "refs/heads/", 11) &&
|
||||
!strncmp(newref, "refs/heads/", 11)) {
|
||||
if (!prefixcmp(oldref, "refs/heads/") &&
|
||||
!prefixcmp(newref, "refs/heads/")) {
|
||||
char oldsection[1024], newsection[1024];
|
||||
|
||||
snprintf(oldsection, 1024, "branch.%s", oldref + 11);
|
||||
@ -894,8 +894,8 @@ static int log_ref_write(const char *ref_name, const unsigned char *old_sha1,
|
||||
log_file = git_path("logs/%s", ref_name);
|
||||
|
||||
if (log_all_ref_updates &&
|
||||
(!strncmp(ref_name, "refs/heads/", 11) ||
|
||||
!strncmp(ref_name, "refs/remotes/", 13) ||
|
||||
(!prefixcmp(ref_name, "refs/heads/") ||
|
||||
!prefixcmp(ref_name, "refs/remotes/") ||
|
||||
!strcmp(ref_name, "HEAD"))) {
|
||||
if (safe_create_leading_directories(log_file) < 0)
|
||||
return error("unable to create directory for %s",
|
||||
|
57
revision.c
57
revision.c
@ -813,11 +813,11 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
|
||||
const char *arg = argv[i];
|
||||
if (*arg == '-') {
|
||||
int opts;
|
||||
if (!strncmp(arg, "--max-count=", 12)) {
|
||||
if (!prefixcmp(arg, "--max-count=")) {
|
||||
revs->max_count = atoi(arg + 12);
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(arg, "--skip=", 7)) {
|
||||
if (!prefixcmp(arg, "--skip=")) {
|
||||
revs->skip_count = atoi(arg + 7);
|
||||
continue;
|
||||
}
|
||||
@ -832,31 +832,31 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
|
||||
revs->max_count = atoi(argv[++i]);
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(arg,"-n",2)) {
|
||||
if (!prefixcmp(arg, "-n")) {
|
||||
revs->max_count = atoi(arg + 2);
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(arg, "--max-age=", 10)) {
|
||||
if (!prefixcmp(arg, "--max-age=")) {
|
||||
revs->max_age = atoi(arg + 10);
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(arg, "--since=", 8)) {
|
||||
if (!prefixcmp(arg, "--since=")) {
|
||||
revs->max_age = approxidate(arg + 8);
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(arg, "--after=", 8)) {
|
||||
if (!prefixcmp(arg, "--after=")) {
|
||||
revs->max_age = approxidate(arg + 8);
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(arg, "--min-age=", 10)) {
|
||||
if (!prefixcmp(arg, "--min-age=")) {
|
||||
revs->min_age = atoi(arg + 10);
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(arg, "--before=", 9)) {
|
||||
if (!prefixcmp(arg, "--before=")) {
|
||||
revs->min_age = approxidate(arg + 9);
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(arg, "--until=", 8)) {
|
||||
if (!prefixcmp(arg, "--until=")) {
|
||||
revs->min_age = approxidate(arg + 8);
|
||||
continue;
|
||||
}
|
||||
@ -944,7 +944,7 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
|
||||
revs->num_ignore_packed = 0;
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(arg, "--unpacked=", 11)) {
|
||||
if (!prefixcmp(arg, "--unpacked=")) {
|
||||
revs->unpacked = 1;
|
||||
add_ignore_packed(revs, arg+11);
|
||||
continue;
|
||||
@ -980,7 +980,7 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
|
||||
revs->verbose_header = 1;
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(arg, "--pretty", 8)) {
|
||||
if (!prefixcmp(arg, "--pretty")) {
|
||||
revs->verbose_header = 1;
|
||||
revs->commit_format = get_commit_format(arg+8);
|
||||
continue;
|
||||
@ -1005,7 +1005,7 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
|
||||
revs->abbrev = DEFAULT_ABBREV;
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(arg, "--abbrev=", 9)) {
|
||||
if (!prefixcmp(arg, "--abbrev=")) {
|
||||
revs->abbrev = strtoul(arg + 9, NULL, 10);
|
||||
if (revs->abbrev < MINIMUM_ABBREV)
|
||||
revs->abbrev = MINIMUM_ABBREV;
|
||||
@ -1034,15 +1034,15 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
|
||||
/*
|
||||
* Grepping the commit log
|
||||
*/
|
||||
if (!strncmp(arg, "--author=", 9)) {
|
||||
if (!prefixcmp(arg, "--author=")) {
|
||||
add_header_grep(revs, "author", arg+9);
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(arg, "--committer=", 12)) {
|
||||
if (!prefixcmp(arg, "--committer=")) {
|
||||
add_header_grep(revs, "committer", arg+12);
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(arg, "--grep=", 7)) {
|
||||
if (!prefixcmp(arg, "--grep=")) {
|
||||
add_message_grep(revs, arg+7);
|
||||
continue;
|
||||
}
|
||||
@ -1050,7 +1050,7 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
|
||||
all_match = 1;
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(arg, "--encoding=", 11)) {
|
||||
if (!prefixcmp(arg, "--encoding=")) {
|
||||
arg += 11;
|
||||
if (strcmp(arg, "none"))
|
||||
git_log_output_encoding = strdup(arg);
|
||||
@ -1233,9 +1233,15 @@ static struct commit *get_revision_1(struct rev_info *revs)
|
||||
*/
|
||||
if (!revs->limited) {
|
||||
if (revs->max_age != -1 &&
|
||||
(commit->date < revs->max_age))
|
||||
continue;
|
||||
add_parents_to_list(revs, commit, &revs->commits);
|
||||
(commit->date < revs->max_age)) {
|
||||
if (revs->boundary)
|
||||
commit->object.flags |=
|
||||
BOUNDARY_SHOW | BOUNDARY;
|
||||
else
|
||||
continue;
|
||||
} else
|
||||
add_parents_to_list(revs, commit,
|
||||
&revs->commits);
|
||||
}
|
||||
if (commit->object.flags & SHOWN)
|
||||
continue;
|
||||
@ -1336,7 +1342,18 @@ struct commit *get_revision(struct rev_info *revs)
|
||||
case -1:
|
||||
break;
|
||||
case 0:
|
||||
return NULL;
|
||||
if (revs->boundary) {
|
||||
struct commit_list *list = revs->commits;
|
||||
while (list) {
|
||||
list->item->object.flags |=
|
||||
BOUNDARY_SHOW | BOUNDARY;
|
||||
list = list->next;
|
||||
}
|
||||
/* all remaining commits are boundary commits */
|
||||
revs->max_count = -1;
|
||||
revs->limited = 1;
|
||||
} else
|
||||
return NULL;
|
||||
default:
|
||||
revs->max_count--;
|
||||
}
|
||||
|
@ -379,11 +379,11 @@ int main(int argc, char **argv)
|
||||
char *arg = *argv;
|
||||
|
||||
if (*arg == '-') {
|
||||
if (!strncmp(arg, "--receive-pack=", 15)) {
|
||||
if (!prefixcmp(arg, "--receive-pack=")) {
|
||||
receivepack = arg + 15;
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(arg, "--exec=", 7)) {
|
||||
if (!prefixcmp(arg, "--exec=")) {
|
||||
receivepack = arg + 7;
|
||||
continue;
|
||||
}
|
||||
|
2
setup.c
2
setup.c
@ -251,7 +251,7 @@ const char *setup_git_directory_gently(int *nongit_ok)
|
||||
offset++;
|
||||
cwd[len++] = '/';
|
||||
cwd[len] = 0;
|
||||
inside_git_dir = !strncmp(cwd + offset, ".git/", 5);
|
||||
inside_git_dir = !prefixcmp(cwd + offset, ".git/");
|
||||
return cwd + offset;
|
||||
}
|
||||
|
||||
|
23
sha1_file.c
23
sha1_file.c
@ -2082,7 +2082,7 @@ int index_fd(unsigned char *sha1, int fd, struct stat *st, int write_object, con
|
||||
{
|
||||
unsigned long size = st->st_size;
|
||||
void *buf;
|
||||
int ret;
|
||||
int ret, re_allocated = 0;
|
||||
|
||||
buf = "";
|
||||
if (size)
|
||||
@ -2091,11 +2091,30 @@ int index_fd(unsigned char *sha1, int fd, struct stat *st, int write_object, con
|
||||
|
||||
if (!type)
|
||||
type = blob_type;
|
||||
/* FIXME: CRLF -> LF conversion here for blobs! We'll need the path! */
|
||||
|
||||
/*
|
||||
* Convert blobs to git internal format
|
||||
*/
|
||||
if (!strcmp(type, blob_type)) {
|
||||
unsigned long nsize = size;
|
||||
char *nbuf = buf;
|
||||
if (convert_to_git(NULL, &nbuf, &nsize)) {
|
||||
if (size)
|
||||
munmap(buf, size);
|
||||
size = nsize;
|
||||
buf = nbuf;
|
||||
re_allocated = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (write_object)
|
||||
ret = write_sha1_file(buf, size, type, sha1);
|
||||
else
|
||||
ret = hash_sha1_file(buf, size, type, sha1);
|
||||
if (re_allocated) {
|
||||
free(buf);
|
||||
return ret;
|
||||
}
|
||||
if (size)
|
||||
munmap(buf, size);
|
||||
return ret;
|
||||
|
2
shell.c
2
shell.c
@ -8,7 +8,7 @@ static int do_generic_cmd(const char *me, char *arg)
|
||||
|
||||
if (!arg || !(arg = sq_dequote(arg)))
|
||||
die("bad argument");
|
||||
if (strncmp(me, "git-", 4))
|
||||
if (prefixcmp(me, "git-"))
|
||||
die("bad command");
|
||||
|
||||
my_argv[0] = me + 4;
|
||||
|
@ -42,9 +42,9 @@ then
|
||||
exit
|
||||
fi
|
||||
|
||||
rawsvnrepo="$svnrepo"
|
||||
svnrepo="file://$svnrepo"
|
||||
|
||||
|
||||
poke() {
|
||||
perl -e '@x = stat($ARGV[0]); utime($x[8], $x[9] + 1, $ARGV[0])' "$1"
|
||||
test-chmtime +1 "$1"
|
||||
}
|
||||
|
217
t/t0020-crlf.sh
Executable file
217
t/t0020-crlf.sh
Executable file
@ -0,0 +1,217 @@
|
||||
#!/bin/sh
|
||||
|
||||
test_description='CRLF conversion'
|
||||
|
||||
. ./test-lib.sh
|
||||
|
||||
append_cr () {
|
||||
sed -e 's/$/Q/' | tr Q '\015'
|
||||
}
|
||||
|
||||
remove_cr () {
|
||||
tr '\015' Q <"$1" | grep Q >/dev/null &&
|
||||
tr '\015' Q <"$1" | sed -ne 's/Q$//p'
|
||||
}
|
||||
|
||||
test_expect_success setup '
|
||||
|
||||
git repo-config core.autocrlf false &&
|
||||
|
||||
for w in Hello world how are you; do echo $w; done >one &&
|
||||
mkdir dir &&
|
||||
for w in I am very very fine thank you; do echo $w; done >dir/two &&
|
||||
git add . &&
|
||||
|
||||
git commit -m initial &&
|
||||
|
||||
one=`git rev-parse HEAD:one` &&
|
||||
dir=`git rev-parse HEAD:dir` &&
|
||||
two=`git rev-parse HEAD:dir/two` &&
|
||||
|
||||
for w in Some extra lines here; do echo $w; done >>one &&
|
||||
git diff >patch.file &&
|
||||
patched=`git hash-object --stdin <one` &&
|
||||
git read-tree --reset -u HEAD &&
|
||||
|
||||
echo happy.
|
||||
'
|
||||
|
||||
test_expect_success 'update with autocrlf=input' '
|
||||
|
||||
rm -f tmp one dir/two &&
|
||||
git read-tree --reset -u HEAD &&
|
||||
git repo-config core.autocrlf input &&
|
||||
|
||||
for f in one dir/two
|
||||
do
|
||||
append_cr <$f >tmp && mv -f tmp $f &&
|
||||
git update-index -- $f || {
|
||||
echo Oops
|
||||
false
|
||||
break
|
||||
}
|
||||
done &&
|
||||
|
||||
differs=`git diff-index --cached HEAD` &&
|
||||
test -z "$differs" || {
|
||||
echo Oops "$differs"
|
||||
false
|
||||
}
|
||||
|
||||
'
|
||||
|
||||
test_expect_success 'update with autocrlf=true' '
|
||||
|
||||
rm -f tmp one dir/two &&
|
||||
git read-tree --reset -u HEAD &&
|
||||
git repo-config core.autocrlf true &&
|
||||
|
||||
for f in one dir/two
|
||||
do
|
||||
append_cr <$f >tmp && mv -f tmp $f &&
|
||||
git update-index -- $f || {
|
||||
echo "Oops $f"
|
||||
false
|
||||
break
|
||||
}
|
||||
done &&
|
||||
|
||||
differs=`git diff-index --cached HEAD` &&
|
||||
test -z "$differs" || {
|
||||
echo Oops "$differs"
|
||||
false
|
||||
}
|
||||
|
||||
'
|
||||
|
||||
test_expect_success 'checkout with autocrlf=true' '
|
||||
|
||||
rm -f tmp one dir/two &&
|
||||
git repo-config core.autocrlf true &&
|
||||
git read-tree --reset -u HEAD &&
|
||||
|
||||
for f in one dir/two
|
||||
do
|
||||
remove_cr "$f" >tmp && mv -f tmp $f &&
|
||||
git update-index -- $f || {
|
||||
echo "Eh? $f"
|
||||
false
|
||||
break
|
||||
}
|
||||
done &&
|
||||
test "$one" = `git hash-object --stdin <one` &&
|
||||
test "$two" = `git hash-object --stdin <dir/two` &&
|
||||
differs=`git diff-index --cached HEAD` &&
|
||||
test -z "$differs" || {
|
||||
echo Oops "$differs"
|
||||
false
|
||||
}
|
||||
'
|
||||
|
||||
test_expect_success 'checkout with autocrlf=input' '
|
||||
|
||||
rm -f tmp one dir/two &&
|
||||
git repo-config core.autocrlf input &&
|
||||
git read-tree --reset -u HEAD &&
|
||||
|
||||
for f in one dir/two
|
||||
do
|
||||
if remove_cr "$f" >/dev/null
|
||||
then
|
||||
echo "Eh? $f"
|
||||
false
|
||||
break
|
||||
else
|
||||
git update-index -- $f
|
||||
fi
|
||||
done &&
|
||||
test "$one" = `git hash-object --stdin <one` &&
|
||||
test "$two" = `git hash-object --stdin <dir/two` &&
|
||||
differs=`git diff-index --cached HEAD` &&
|
||||
test -z "$differs" || {
|
||||
echo Oops "$differs"
|
||||
false
|
||||
}
|
||||
'
|
||||
|
||||
test_expect_success 'apply patch (autocrlf=input)' '
|
||||
|
||||
rm -f tmp one dir/two &&
|
||||
git repo-config core.autocrlf input &&
|
||||
git read-tree --reset -u HEAD &&
|
||||
|
||||
git apply patch.file &&
|
||||
test "$patched" = "`git hash-object --stdin <one`" || {
|
||||
echo "Eh? apply without index"
|
||||
false
|
||||
}
|
||||
'
|
||||
|
||||
test_expect_success 'apply patch --cached (autocrlf=input)' '
|
||||
|
||||
rm -f tmp one dir/two &&
|
||||
git repo-config core.autocrlf input &&
|
||||
git read-tree --reset -u HEAD &&
|
||||
|
||||
git apply --cached patch.file &&
|
||||
test "$patched" = `git rev-parse :one` || {
|
||||
echo "Eh? apply with --cached"
|
||||
false
|
||||
}
|
||||
'
|
||||
|
||||
test_expect_success 'apply patch --index (autocrlf=input)' '
|
||||
|
||||
rm -f tmp one dir/two &&
|
||||
git repo-config core.autocrlf input &&
|
||||
git read-tree --reset -u HEAD &&
|
||||
|
||||
git apply --index patch.file &&
|
||||
test "$patched" = `git rev-parse :one` &&
|
||||
test "$patched" = `git hash-object --stdin <one` || {
|
||||
echo "Eh? apply with --index"
|
||||
false
|
||||
}
|
||||
'
|
||||
|
||||
test_expect_success 'apply patch (autocrlf=true)' '
|
||||
|
||||
rm -f tmp one dir/two &&
|
||||
git repo-config core.autocrlf true &&
|
||||
git read-tree --reset -u HEAD &&
|
||||
|
||||
git apply patch.file &&
|
||||
test "$patched" = "`remove_cr one | git hash-object --stdin`" || {
|
||||
echo "Eh? apply without index"
|
||||
false
|
||||
}
|
||||
'
|
||||
|
||||
test_expect_success 'apply patch --cached (autocrlf=true)' '
|
||||
|
||||
rm -f tmp one dir/two &&
|
||||
git repo-config core.autocrlf true &&
|
||||
git read-tree --reset -u HEAD &&
|
||||
|
||||
git apply --cached patch.file &&
|
||||
test "$patched" = `git rev-parse :one` || {
|
||||
echo "Eh? apply without index"
|
||||
false
|
||||
}
|
||||
'
|
||||
|
||||
test_expect_success 'apply patch --index (autocrlf=true)' '
|
||||
|
||||
rm -f tmp one dir/two &&
|
||||
git repo-config core.autocrlf true &&
|
||||
git read-tree --reset -u HEAD &&
|
||||
|
||||
git apply --index patch.file &&
|
||||
test "$patched" = `git rev-parse :one` &&
|
||||
test "$patched" = "`remove_cr one | git hash-object --stdin`" || {
|
||||
echo "Eh? apply with --index"
|
||||
false
|
||||
}
|
||||
'
|
||||
|
||||
test_done
|
@ -13,6 +13,10 @@ P1='pathname with HT'
|
||||
P2='pathname with SP'
|
||||
P3='pathname
|
||||
with LF'
|
||||
: >"$P1" 2>&1 && test -f "$P1" && rm -f "$P1" || {
|
||||
echo >&2 'Filesystem does not support tabs in names'
|
||||
test_done
|
||||
}
|
||||
|
||||
test_expect_success setup '
|
||||
echo P0.0 >"$P0.0" &&
|
||||
|
162
t/t4119-apply-config.sh
Executable file
162
t/t4119-apply-config.sh
Executable file
@ -0,0 +1,162 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2007 Junio C Hamano
|
||||
#
|
||||
|
||||
test_description='git-apply --whitespace=strip and configuration file.
|
||||
|
||||
'
|
||||
|
||||
. ./test-lib.sh
|
||||
|
||||
test_expect_success setup '
|
||||
mkdir sub &&
|
||||
echo A >sub/file1 &&
|
||||
cp sub/file1 saved &&
|
||||
git add sub/file1 &&
|
||||
echo "B " >sub/file1 &&
|
||||
git diff >patch.file
|
||||
'
|
||||
|
||||
# Also handcraft GNU diff output; note this has trailing whitespace.
|
||||
cat >gpatch.file <<\EOF &&
|
||||
--- file1 2007-02-21 01:04:24.000000000 -0800
|
||||
+++ file1+ 2007-02-21 01:07:44.000000000 -0800
|
||||
@@ -1 +1 @@
|
||||
-A
|
||||
+B
|
||||
EOF
|
||||
|
||||
sed -e 's|file1|sub/&|' gpatch.file >gpatch-sub.file &&
|
||||
sed -e '
|
||||
/^--- /s|file1|a/sub/&|
|
||||
/^+++ /s|file1|b/sub/&|
|
||||
' gpatch.file >gpatch-ab-sub.file &&
|
||||
|
||||
check_result () {
|
||||
if grep " " "$1"
|
||||
then
|
||||
echo "Eh?"
|
||||
false
|
||||
elif grep B "$1"
|
||||
then
|
||||
echo Happy
|
||||
else
|
||||
echo "Huh?"
|
||||
false
|
||||
fi
|
||||
}
|
||||
|
||||
test_expect_success 'apply --whitespace=strip' '
|
||||
|
||||
rm -f sub/file1 &&
|
||||
cp saved sub/file1 &&
|
||||
git update-index --refresh &&
|
||||
|
||||
git apply --whitespace=strip patch.file &&
|
||||
check_result sub/file1
|
||||
'
|
||||
|
||||
test_expect_success 'apply --whitespace=strip from config' '
|
||||
|
||||
rm -f sub/file1 &&
|
||||
cp saved sub/file1 &&
|
||||
git update-index --refresh &&
|
||||
|
||||
git config apply.whitespace strip &&
|
||||
git apply patch.file &&
|
||||
check_result sub/file1
|
||||
'
|
||||
|
||||
D=`pwd`
|
||||
|
||||
test_expect_success 'apply --whitespace=strip in subdir' '
|
||||
|
||||
cd "$D" &&
|
||||
git config --unset-all apply.whitespace
|
||||
rm -f sub/file1 &&
|
||||
cp saved sub/file1 &&
|
||||
git update-index --refresh &&
|
||||
|
||||
cd sub &&
|
||||
git apply --whitespace=strip ../patch.file &&
|
||||
check_result file1
|
||||
'
|
||||
|
||||
test_expect_success 'apply --whitespace=strip from config in subdir' '
|
||||
|
||||
cd "$D" &&
|
||||
git config apply.whitespace strip &&
|
||||
rm -f sub/file1 &&
|
||||
cp saved sub/file1 &&
|
||||
git update-index --refresh &&
|
||||
|
||||
cd sub &&
|
||||
git apply ../patch.file &&
|
||||
check_result file1
|
||||
'
|
||||
|
||||
test_expect_success 'same in subdir but with traditional patch input' '
|
||||
|
||||
cd "$D" &&
|
||||
git config apply.whitespace strip &&
|
||||
rm -f sub/file1 &&
|
||||
cp saved sub/file1 &&
|
||||
git update-index --refresh &&
|
||||
|
||||
cd sub &&
|
||||
git apply ../gpatch.file &&
|
||||
check_result file1
|
||||
'
|
||||
|
||||
test_expect_success 'same but with traditional patch input of depth 1' '
|
||||
|
||||
cd "$D" &&
|
||||
git config apply.whitespace strip &&
|
||||
rm -f sub/file1 &&
|
||||
cp saved sub/file1 &&
|
||||
git update-index --refresh &&
|
||||
|
||||
cd sub &&
|
||||
git apply ../gpatch-sub.file &&
|
||||
check_result file1
|
||||
'
|
||||
|
||||
test_expect_success 'same but with traditional patch input of depth 2' '
|
||||
|
||||
cd "$D" &&
|
||||
git config apply.whitespace strip &&
|
||||
rm -f sub/file1 &&
|
||||
cp saved sub/file1 &&
|
||||
git update-index --refresh &&
|
||||
|
||||
cd sub &&
|
||||
git apply ../gpatch-ab-sub.file &&
|
||||
check_result file1
|
||||
'
|
||||
|
||||
test_expect_success 'same but with traditional patch input of depth 1' '
|
||||
|
||||
cd "$D" &&
|
||||
git config apply.whitespace strip &&
|
||||
rm -f sub/file1 &&
|
||||
cp saved sub/file1 &&
|
||||
git update-index --refresh &&
|
||||
|
||||
git apply -p0 gpatch-sub.file &&
|
||||
check_result sub/file1
|
||||
'
|
||||
|
||||
test_expect_success 'same but with traditional patch input of depth 2' '
|
||||
|
||||
cd "$D" &&
|
||||
git config apply.whitespace strip &&
|
||||
rm -f sub/file1 &&
|
||||
cp saved sub/file1 &&
|
||||
git update-index --refresh &&
|
||||
|
||||
git apply gpatch-ab-sub.file &&
|
||||
check_result sub/file1
|
||||
'
|
||||
|
||||
test_done
|
@ -112,39 +112,26 @@ rr2=.git/rr-cache/$sha2
|
||||
mkdir $rr2
|
||||
echo Hello > $rr2/preimage
|
||||
|
||||
case "$(date -d @11111111 +%s 2>/dev/null)" in
|
||||
11111111)
|
||||
# 'date' must be able to take arbitrary input with @11111111 notation.
|
||||
# for this test to succeed. We should fix this part using more
|
||||
# portable script someday.
|
||||
almost_15_days_ago=$((60-15*86400))
|
||||
just_over_15_days_ago=$((-1-15*86400))
|
||||
almost_60_days_ago=$((60-60*86400))
|
||||
just_over_60_days_ago=$((-1-60*86400))
|
||||
|
||||
now=$(date +%s)
|
||||
almost_15_days_ago=$(($now+60-15*86400))
|
||||
just_over_15_days_ago=$(($now-1-15*86400))
|
||||
almost_60_days_ago=$(($now+60-60*86400))
|
||||
just_over_60_days_ago=$(($now-1-60*86400))
|
||||
predate1="$(date -d "@$almost_60_days_ago" +%Y%m%d%H%M.%S)"
|
||||
predate2="$(date -d "@$almost_15_days_ago" +%Y%m%d%H%M.%S)"
|
||||
postdate1="$(date -d "@$just_over_60_days_ago" +%Y%m%d%H%M.%S)"
|
||||
postdate2="$(date -d "@$just_over_15_days_ago" +%Y%m%d%H%M.%S)"
|
||||
test-chmtime =$almost_60_days_ago $rr/preimage
|
||||
test-chmtime =$almost_15_days_ago $rr2/preimage
|
||||
|
||||
touch -m -t "$predate1" $rr/preimage
|
||||
touch -m -t "$predate2" $rr2/preimage
|
||||
test_expect_success 'garbage collection (part1)' 'git rerere gc'
|
||||
|
||||
test_expect_success 'garbage collection (part1)' 'git rerere gc'
|
||||
test_expect_success 'young records still live' \
|
||||
"test -f $rr/preimage && test -f $rr2/preimage"
|
||||
|
||||
test_expect_success 'young records still live' \
|
||||
"test -f $rr/preimage -a -f $rr2/preimage"
|
||||
test-chmtime =$just_over_60_days_ago $rr/preimage
|
||||
test-chmtime =$just_over_15_days_ago $rr2/preimage
|
||||
|
||||
touch -m -t "$postdate1" $rr/preimage
|
||||
touch -m -t "$postdate2" $rr2/preimage
|
||||
test_expect_success 'garbage collection (part2)' 'git rerere gc'
|
||||
|
||||
test_expect_success 'garbage collection (part2)' 'git rerere gc'
|
||||
|
||||
test_expect_success 'old records rest in peace' \
|
||||
"test ! -f $rr/preimage -a ! -f $rr2/preimage"
|
||||
;;
|
||||
esac
|
||||
test_expect_success 'old records rest in peace' \
|
||||
"test ! -f $rr/preimage && test ! -f $rr2/preimage"
|
||||
|
||||
test_done
|
||||
|
||||
|
@ -211,8 +211,58 @@ tree d667270a1f7b109f5eb3aaea21ede14b56bfdd6e
|
||||
tree 8f51f74cf0163afc9ad68a4b1537288c4558b5a4
|
||||
EOF
|
||||
|
||||
echo tree 4b825dc642cb6eb9a060e54bf8d69288fbee4904 >> expected
|
||||
|
||||
test_expect_success "$name" "diff -u a expected"
|
||||
|
||||
test_expect_failure 'exit if remote refs are ambigious' "
|
||||
git-config --add svn-remote.svn.fetch \
|
||||
bar:refs/remotes/git-svn &&
|
||||
git-svn migrate
|
||||
"
|
||||
|
||||
test_expect_failure 'exit if init-ing a would clobber a URL' "
|
||||
svnadmin create ${PWD}/svnrepo2 &&
|
||||
svn mkdir -m 'mkdir bar' ${svnrepo}2/bar &&
|
||||
git-config --unset svn-remote.svn.fetch \
|
||||
'^bar:refs/remotes/git-svn$' &&
|
||||
git-svn init ${svnrepo}2/bar
|
||||
"
|
||||
|
||||
test_expect_success \
|
||||
'init allows us to connect to another directory in the same repo' "
|
||||
git-svn init -i bar $svnrepo/bar &&
|
||||
git config --get svn-remote.svn.fetch \
|
||||
'^bar:refs/remotes/bar$' &&
|
||||
git config --get svn-remote.svn.fetch \
|
||||
'^:refs/remotes/git-svn$'
|
||||
"
|
||||
|
||||
test_expect_success 'able to dcommit to a subdirectory' "
|
||||
git-svn fetch -i bar &&
|
||||
git checkout -b my-bar refs/remotes/bar &&
|
||||
echo abc > d &&
|
||||
git update-index --add d &&
|
||||
git commit -m '/bar/d should be in the log' &&
|
||||
git-svn dcommit -i bar &&
|
||||
test -z \"\`git diff refs/heads/my-bar refs/remotes/bar\`\" &&
|
||||
mkdir newdir &&
|
||||
echo new > newdir/dir &&
|
||||
git update-index --add newdir/dir &&
|
||||
git commit -m 'add a new directory' &&
|
||||
git-svn dcommit -i bar &&
|
||||
test -z \"\`git diff refs/heads/my-bar refs/remotes/bar\`\" &&
|
||||
echo foo >> newdir/dir &&
|
||||
git update-index newdir/dir &&
|
||||
git commit -m 'modify a file in new directory' &&
|
||||
git-svn dcommit -i bar &&
|
||||
test -z \"\`git diff refs/heads/my-bar refs/remotes/bar\`\"
|
||||
"
|
||||
|
||||
test_expect_success 'able to set-tree to a subdirectory' "
|
||||
echo cba > d &&
|
||||
git update-index d &&
|
||||
git commit -m 'update /bar/d' &&
|
||||
git-svn set-tree -i bar HEAD &&
|
||||
test -z \"\`git diff refs/heads/my-bar refs/remotes/bar\`\"
|
||||
"
|
||||
|
||||
test_done
|
||||
|
@ -121,4 +121,30 @@ b_ne_cr="`git-hash-object ne_cr`"
|
||||
test_expect_success 'CRLF + $Id$' "test '$a_cr' = '$b_cr'"
|
||||
test_expect_success 'CRLF + $Id$ (no newline)' "test '$a_ne_cr' = '$b_ne_cr'"
|
||||
|
||||
cat > show-ignore.expect <<\EOF
|
||||
|
||||
# /
|
||||
/no-such-file*
|
||||
|
||||
# deeply
|
||||
/deeply/no-such-file*
|
||||
|
||||
# deeply/nested
|
||||
/deeply/nested/no-such-file*
|
||||
|
||||
# deeply/nested/directory
|
||||
/deeply/nested/directory/no-such-file*
|
||||
EOF
|
||||
|
||||
test_expect_success 'test show-ignore' "
|
||||
cd test_wc &&
|
||||
mkdir -p deeply/nested/directory &&
|
||||
svn add deeply &&
|
||||
svn propset -R svn:ignore 'no-such-file*' .
|
||||
svn commit -m 'propset svn:ignore'
|
||||
cd .. &&
|
||||
git-svn show-ignore > show-ignore.got &&
|
||||
cmp show-ignore.expect show-ignore.got
|
||||
"
|
||||
|
||||
test_done
|
||||
|
@ -1,61 +0,0 @@
|
||||
#!/bin/sh
|
||||
test_description='git-svn graft-branches'
|
||||
. ./lib-git-svn.sh
|
||||
|
||||
svnrepo="$svnrepo/test-git-svn"
|
||||
|
||||
test_expect_success 'initialize repo' "
|
||||
mkdir import &&
|
||||
cd import &&
|
||||
mkdir -p trunk branches tags &&
|
||||
echo hello > trunk/readme &&
|
||||
svn import -m 'import for git-svn' . $svnrepo &&
|
||||
cd .. &&
|
||||
svn cp -m 'tag a' $svnrepo/trunk $svnrepo/tags/a &&
|
||||
svn cp -m 'branch a' $svnrepo/trunk $svnrepo/branches/a &&
|
||||
svn co $svnrepo wc &&
|
||||
cd wc &&
|
||||
echo feedme >> branches/a/readme &&
|
||||
poke branches/a/readme &&
|
||||
svn commit -m hungry &&
|
||||
cd trunk &&
|
||||
svn merge -r3:4 $svnrepo/branches/a &&
|
||||
svn commit -m 'merge with a' &&
|
||||
cd ../.. &&
|
||||
git-svn multi-init $svnrepo -T trunk -b branches -t tags &&
|
||||
git-svn multi-fetch
|
||||
"
|
||||
|
||||
r1=`git-rev-list remotes/trunk | tail -n1`
|
||||
r2=`git-rev-list remotes/tags/a | tail -n1`
|
||||
r3=`git-rev-list remotes/a | tail -n1`
|
||||
r4=`git-rev-parse remotes/a`
|
||||
r5=`git-rev-parse remotes/trunk`
|
||||
|
||||
test_expect_success 'test graft-branches regexes and copies' "
|
||||
test -n "$r1" &&
|
||||
test -n "$r2" &&
|
||||
test -n "$r3" &&
|
||||
test -n "$r4" &&
|
||||
test -n "$r5" &&
|
||||
git-svn graft-branches &&
|
||||
grep '^$r2 $r1' $GIT_DIR/info/grafts &&
|
||||
grep '^$r3 $r1' $GIT_DIR/info/grafts &&
|
||||
grep '^$r5 ' $GIT_DIR/info/grafts | grep '$r4' | grep '$r1'
|
||||
"
|
||||
|
||||
test_debug 'gitk --all & sleep 1'
|
||||
|
||||
test_expect_success 'test graft-branches with tree-joins' "
|
||||
rm $GIT_DIR/info/grafts &&
|
||||
git-svn graft-branches --no-default-regex --no-graft-copy -B &&
|
||||
grep '^$r3 ' $GIT_DIR/info/grafts | grep '$r1' | grep '$r2' &&
|
||||
grep '^$r2 $r1' $GIT_DIR/info/grafts &&
|
||||
grep '^$r5 ' $GIT_DIR/info/grafts | grep '$r1' | grep '$r4'
|
||||
"
|
||||
|
||||
# the result of this is kinda funky, we have a strange history and
|
||||
# this is just a test :)
|
||||
test_debug 'gitk --all &'
|
||||
|
||||
test_done
|
@ -3,7 +3,7 @@
|
||||
# Copyright (c) 2006 Eric Wong
|
||||
#
|
||||
|
||||
test_description='git-svn --follow-parent fetching'
|
||||
test_description='git-svn fetching'
|
||||
. ./lib-git-svn.sh
|
||||
|
||||
test_expect_success 'initialize repo' "
|
||||
@ -27,11 +27,141 @@ test_expect_success 'initialize repo' "
|
||||
cd ..
|
||||
"
|
||||
|
||||
test_expect_success 'init and fetch --follow-parent a moved directory' "
|
||||
test_expect_success 'init and fetch a moved directory' "
|
||||
git-svn init -i thunk $svnrepo/thunk &&
|
||||
git-svn fetch --follow-parent -i thunk &&
|
||||
git-rev-parse --verify refs/remotes/trunk &&
|
||||
test '$?' -eq '0'
|
||||
git-svn fetch -i thunk &&
|
||||
test \"\`git-rev-parse --verify refs/remotes/thunk@2\`\" \
|
||||
= \"\`git-rev-parse --verify refs/remotes/thunk~1\`\" &&
|
||||
test \"\`git-cat-file blob refs/remotes/thunk:readme |\
|
||||
sed -n -e '3p'\`\" = goodbye &&
|
||||
test -z \"\`git-config --get svn-remote.svn.fetch \
|
||||
'^trunk:refs/remotes/thunk@2$'\`\"
|
||||
"
|
||||
|
||||
test_expect_success 'init and fetch from one svn-remote' "
|
||||
git-config svn-remote.svn.url $svnrepo &&
|
||||
git-config --add svn-remote.svn.fetch \
|
||||
trunk:refs/remotes/svn/trunk &&
|
||||
git-config --add svn-remote.svn.fetch \
|
||||
thunk:refs/remotes/svn/thunk &&
|
||||
git-svn fetch -i svn/thunk &&
|
||||
test \"\`git-rev-parse --verify refs/remotes/svn/trunk\`\" \
|
||||
= \"\`git-rev-parse --verify refs/remotes/svn/thunk~1\`\" &&
|
||||
test \"\`git-cat-file blob refs/remotes/svn/thunk:readme |\
|
||||
sed -n -e '3p'\`\" = goodbye
|
||||
"
|
||||
|
||||
test_expect_success 'follow deleted parent' "
|
||||
svn cp -m 'resurrecting trunk as junk' \
|
||||
-r2 $svnrepo/trunk $svnrepo/junk &&
|
||||
git-config --add svn-remote.svn.fetch \
|
||||
junk:refs/remotes/svn/junk &&
|
||||
git-svn fetch -i svn/thunk &&
|
||||
git-svn fetch -i svn/junk &&
|
||||
test -z \"\`git diff svn/junk svn/trunk\`\" &&
|
||||
test \"\`git merge-base svn/junk svn/trunk\`\" \
|
||||
= \"\`git rev-parse svn/trunk\`\"
|
||||
"
|
||||
|
||||
test_expect_success 'follow larger parent' "
|
||||
mkdir -p import/trunk/thunk/bump/thud &&
|
||||
echo hi > import/trunk/thunk/bump/thud/file &&
|
||||
svn import -m 'import a larger parent' import $svnrepo/larger-parent &&
|
||||
svn cp -m 'hi' $svnrepo/larger-parent $svnrepo/another-larger &&
|
||||
git-svn init -i larger $svnrepo/another-larger/trunk/thunk/bump/thud &&
|
||||
git-svn fetch -i larger &&
|
||||
git-rev-parse --verify refs/remotes/larger &&
|
||||
git-rev-parse --verify \
|
||||
refs/remotes/larger-parent/trunk/thunk/bump/thud &&
|
||||
test \"\`git-merge-base \
|
||||
refs/remotes/larger-parent/trunk/thunk/bump/thud \
|
||||
refs/remotes/larger\`\" = \
|
||||
\"\`git-rev-parse refs/remotes/larger\`\"
|
||||
true
|
||||
"
|
||||
|
||||
test_expect_success 'follow higher-level parent' "
|
||||
svn mkdir -m 'follow higher-level parent' $svnrepo/blob &&
|
||||
svn co $svnrepo/blob blob &&
|
||||
cd blob &&
|
||||
echo hi > hi &&
|
||||
svn add hi &&
|
||||
svn commit -m 'hihi' &&
|
||||
cd ..
|
||||
svn mkdir -m 'new glob at top level' $svnrepo/glob &&
|
||||
svn mv -m 'move blob down a level' $svnrepo/blob $svnrepo/glob/blob &&
|
||||
git-svn init -i blob $svnrepo/glob/blob &&
|
||||
git-svn fetch -i blob
|
||||
"
|
||||
|
||||
test_expect_success 'follow deleted directory' "
|
||||
svn mv -m 'bye!' $svnrepo/glob/blob/hi $svnrepo/glob/blob/bye &&
|
||||
svn rm -m 'remove glob' $svnrepo/glob &&
|
||||
git-svn init -i glob $svnrepo/glob &&
|
||||
git-svn fetch -i glob &&
|
||||
test \"\`git cat-file blob refs/remotes/glob:blob/bye\`\" = hi &&
|
||||
test \"\`git ls-tree refs/remotes/glob | wc -l \`\" -eq 1
|
||||
"
|
||||
|
||||
# ref: r9270 of the Subversion repository: (http://svn.collab.net/repos/svn)
|
||||
# in trunk/subversion/bindings/swig/perl
|
||||
test_expect_success 'follow-parent avoids deleting relevant info' "
|
||||
mkdir -p import/trunk/subversion/bindings/swig/perl/t &&
|
||||
for i in a b c ; do \
|
||||
echo \$i > import/trunk/subversion/bindings/swig/perl/\$i.pm &&
|
||||
echo _\$i > import/trunk/subversion/bindings/swig/perl/t/\$i.t; \
|
||||
done &&
|
||||
echo 'bad delete test' > \
|
||||
import/trunk/subversion/bindings/swig/perl/t/larger-parent &&
|
||||
echo 'bad delete test 2' > \
|
||||
import/trunk/subversion/bindings/swig/perl/another-larger &&
|
||||
cd import &&
|
||||
svn import -m 'r9270 test' . $svnrepo/r9270 &&
|
||||
cd .. &&
|
||||
svn co $svnrepo/r9270/trunk/subversion/bindings/swig/perl r9270 &&
|
||||
cd r9270 &&
|
||||
svn mkdir native &&
|
||||
svn mv t native/t &&
|
||||
for i in a b c; do svn mv \$i.pm native/\$i.pm; done &&
|
||||
echo z >> native/t/c.t &&
|
||||
poke native/t/c.t &&
|
||||
svn commit -m 'reorg test' &&
|
||||
cd .. &&
|
||||
git-svn init -i r9270-t \
|
||||
$svnrepo/r9270/trunk/subversion/bindings/swig/perl/native/t &&
|
||||
git-svn fetch -i r9270-t &&
|
||||
test \`git rev-list r9270-t | wc -l\` -eq 2 &&
|
||||
test \"\`git ls-tree --name-only r9270-t~1\`\" = \
|
||||
\"\`git ls-tree --name-only r9270-t\`\"
|
||||
"
|
||||
|
||||
test_expect_success "track initial change if it was only made to parent" "
|
||||
svn cp -m 'wheee!' $svnrepo/r9270/trunk $svnrepo/r9270/drunk &&
|
||||
git-svn init -i r9270-d \
|
||||
$svnrepo/r9270/drunk/subversion/bindings/swig/perl/native/t &&
|
||||
git-svn fetch -i r9270-d &&
|
||||
test \`git rev-list r9270-d | wc -l\` -eq 3 &&
|
||||
test \"\`git ls-tree --name-only r9270-t\`\" = \
|
||||
\"\`git ls-tree --name-only r9270-d\`\" &&
|
||||
test \"\`git rev-parse r9270-t\`\" = \
|
||||
\"\`git rev-parse r9270-d~1\`\"
|
||||
"
|
||||
|
||||
test_expect_success "track multi-parent paths" "
|
||||
svn cp -m 'resurrect /glob' $svnrepo/r9270 $svnrepo/glob &&
|
||||
git-svn multi-fetch &&
|
||||
test \`git cat-file commit refs/remotes/glob | \
|
||||
grep '^parent ' | wc -l\` -eq 2
|
||||
"
|
||||
|
||||
test_expect_success "multi-fetch continues to work" "
|
||||
git-svn multi-fetch
|
||||
"
|
||||
|
||||
test_expect_success "multi-fetch works off a 'clean' repository" "
|
||||
rm -r $GIT_DIR/svn $GIT_DIR/refs/remotes $GIT_DIR/logs &&
|
||||
mkdir $GIT_DIR/svn &&
|
||||
git-svn multi-fetch
|
||||
"
|
||||
|
||||
test_debug 'gitk --all &'
|
||||
|
@ -31,4 +31,13 @@ test_expect_success 'test the commit-diff command' "
|
||||
cmp readme wc/readme
|
||||
"
|
||||
|
||||
test_expect_success 'commit-diff to a sub-directory (with git-svn config)' "
|
||||
svn import -m 'sub-directory' import $svnrepo/subdir &&
|
||||
git-svn init $svnrepo/subdir &&
|
||||
git-svn fetch &&
|
||||
git-svn commit-diff -r3 '$prev' '$head' &&
|
||||
svn cat $svnrepo/subdir/readme > readme.2 &&
|
||||
cmp readme readme.2
|
||||
"
|
||||
|
||||
test_done
|
||||
|
112
t/t9107-git-svn-migrate.sh
Executable file
112
t/t9107-git-svn-migrate.sh
Executable file
@ -0,0 +1,112 @@
|
||||
#!/bin/sh
|
||||
# Copyright (c) 2006 Eric Wong
|
||||
test_description='git-svn metadata migrations from previous versions'
|
||||
. ./lib-git-svn.sh
|
||||
|
||||
test_expect_success 'setup old-looking metadata' "
|
||||
cp $GIT_DIR/config $GIT_DIR/config-old-git-svn &&
|
||||
mkdir import &&
|
||||
cd import &&
|
||||
for i in trunk branches/a branches/b \
|
||||
tags/0.1 tags/0.2 tags/0.3; do
|
||||
mkdir -p \$i && \
|
||||
echo hello >> \$i/README || exit 1
|
||||
done && \
|
||||
svn import -m test . $svnrepo
|
||||
cd .. &&
|
||||
git-svn init $svnrepo &&
|
||||
git-svn fetch &&
|
||||
mv $GIT_DIR/svn/* $GIT_DIR/ &&
|
||||
mv $GIT_DIR/svn/.metadata $GIT_DIR/ &&
|
||||
rmdir $GIT_DIR/svn &&
|
||||
git-update-ref refs/heads/git-svn-HEAD refs/remotes/git-svn &&
|
||||
git-update-ref refs/heads/svn-HEAD refs/remotes/git-svn &&
|
||||
git-update-ref -d refs/remotes/git-svn refs/remotes/git-svn
|
||||
"
|
||||
|
||||
head=`git rev-parse --verify refs/heads/git-svn-HEAD^0`
|
||||
test_expect_success 'git-svn-HEAD is a real HEAD' "test -n '$head'"
|
||||
|
||||
test_expect_success 'initialize old-style (v0) git-svn layout' "
|
||||
mkdir -p $GIT_DIR/git-svn/info $GIT_DIR/svn/info &&
|
||||
echo $svnrepo > $GIT_DIR/git-svn/info/url &&
|
||||
echo $svnrepo > $GIT_DIR/svn/info/url &&
|
||||
git-svn migrate &&
|
||||
! test -d $GIT_DIR/git-svn &&
|
||||
git-rev-parse --verify refs/remotes/git-svn^0 &&
|
||||
git-rev-parse --verify refs/remotes/svn^0 &&
|
||||
test \`git config --get svn-remote.svn.url\` = '$svnrepo' &&
|
||||
test \`git config --get svn-remote.svn.fetch\` = \
|
||||
':refs/remotes/git-svn'
|
||||
"
|
||||
|
||||
test_expect_success 'initialize a multi-repository repo' "
|
||||
git-svn init $svnrepo -T trunk -t tags -b branches &&
|
||||
git-config --get-all svn-remote.svn.fetch > fetch.out &&
|
||||
grep '^trunk:refs/remotes/trunk$' fetch.out &&
|
||||
test -n \"\`git-config --get svn-remote.svn.branches \
|
||||
'^branches/\*:refs/remotes/\*$'\`\" &&
|
||||
test -n \"\`git-config --get svn-remote.svn.tags \
|
||||
'^tags/\*:refs/remotes/tags/\*$'\`\" &&
|
||||
git config --unset svn-remote.svn.branches \
|
||||
'^branches/\*:refs/remotes/\*$' &&
|
||||
git config --unset svn-remote.svn.tags \
|
||||
'^tags/\*:refs/remotes/tags/\*$' &&
|
||||
git-config --add svn-remote.svn.fetch 'branches/a:refs/remotes/a' &&
|
||||
git-config --add svn-remote.svn.fetch 'branches/b:refs/remotes/b' &&
|
||||
for i in tags/0.1 tags/0.2 tags/0.3; do
|
||||
git-config --add svn-remote.svn.fetch \
|
||||
\$i:refs/remotes/\$i || exit 1; done
|
||||
"
|
||||
|
||||
# refs should all be different, but the trees should all be the same:
|
||||
test_expect_success 'multi-fetch works on partial urls + paths' "
|
||||
git-svn multi-fetch &&
|
||||
for i in trunk a b tags/0.1 tags/0.2 tags/0.3; do
|
||||
git rev-parse --verify refs/remotes/\$i^0 >> refs.out || exit 1;
|
||||
done &&
|
||||
test -z \"\`sort < refs.out | uniq -d\`\" &&
|
||||
for i in trunk a b tags/0.1 tags/0.2 tags/0.3; do
|
||||
for j in trunk a b tags/0.1 tags/0.2 tags/0.3; do
|
||||
if test \$j != \$i; then continue; fi
|
||||
test -z \"\`git diff refs/remotes/\$i \
|
||||
refs/remotes/\$j\`\" ||exit 1; done; done
|
||||
"
|
||||
|
||||
test_expect_success 'migrate --minimize on old inited layout' "
|
||||
git config --unset-all svn-remote.svn.fetch &&
|
||||
git config --unset-all svn-remote.svn.url &&
|
||||
rm -rf $GIT_DIR/svn &&
|
||||
for i in \`cat fetch.out\`; do
|
||||
path=\`expr \$i : '\\([^:]*\\):.*$'\`
|
||||
ref=\`expr \$i : '[^:]*:refs/remotes/\\(.*\\)$'\`
|
||||
if test -z \"\$ref\"; then continue; fi
|
||||
if test -n \"\$path\"; then path=\"/\$path\"; fi
|
||||
( mkdir -p $GIT_DIR/svn/\$ref/info/ &&
|
||||
echo $svnrepo\$path > $GIT_DIR/svn/\$ref/info/url ) || exit 1;
|
||||
done &&
|
||||
git-svn migrate --minimize &&
|
||||
test -z \"\`git-config -l |grep -v '^svn-remote\.git-svn\.'\`\" &&
|
||||
git-config --get-all svn-remote.svn.fetch > fetch.out &&
|
||||
grep '^trunk:refs/remotes/trunk$' fetch.out &&
|
||||
grep '^branches/a:refs/remotes/a$' fetch.out &&
|
||||
grep '^branches/b:refs/remotes/b$' fetch.out &&
|
||||
grep '^tags/0\.1:refs/remotes/tags/0\.1$' fetch.out &&
|
||||
grep '^tags/0\.2:refs/remotes/tags/0\.2$' fetch.out &&
|
||||
grep '^tags/0\.3:refs/remotes/tags/0\.3$' fetch.out
|
||||
grep '^:refs/remotes/git-svn' fetch.out
|
||||
"
|
||||
|
||||
test_expect_success ".rev_db auto-converted to .rev_db.UUID" "
|
||||
git-svn fetch -i trunk &&
|
||||
expect=$GIT_DIR/svn/trunk/.rev_db.* &&
|
||||
test -n \"\$expect\" &&
|
||||
mv \$expect $GIT_DIR/svn/trunk/.rev_db &&
|
||||
git-svn fetch -i trunk &&
|
||||
test -L $GIT_DIR/svn/trunk/.rev_db &&
|
||||
test -f \$expect &&
|
||||
cmp \$expect $GIT_DIR/svn/trunk/.rev_db
|
||||
"
|
||||
|
||||
test_done
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user