Merge commit 'mingw/master' into devel

This commit is contained in:
Steffen Prohaska
2008-05-21 23:13:05 +02:00
179 changed files with 7406 additions and 2185 deletions

View File

@@ -2,8 +2,8 @@ MAN1_TXT= \
$(filter-out $(addsuffix .txt, $(ARTICLES) $(SP_ARTICLES)), \
$(wildcard git-*.txt)) \
gitk.txt
MAN5_TXT=gitattributes.txt gitignore.txt gitcli.txt gitmodules.txt
MAN7_TXT=git.txt
MAN5_TXT=gitattributes.txt gitignore.txt gitmodules.txt githooks.txt
MAN7_TXT=git.txt gitcli.txt
MAN_TXT = $(MAN1_TXT) $(MAN5_TXT) $(MAN7_TXT)
MAN_XML=$(patsubst %.txt,%.xml,$(MAN_TXT))
@@ -18,7 +18,6 @@ ARTICLES += cvs-migration
ARTICLES += diffcore
ARTICLES += howto-index
ARTICLES += repository-layout
ARTICLES += hooks
ARTICLES += everyday
ARTICLES += git-tools
ARTICLES += glossary

View File

@@ -399,6 +399,21 @@ branch.autosetupmerge::
done when the starting point is either a local branch or remote
branch. This option defaults to true.
branch.autosetuprebase::
When a new branch is created with `git-branch` or `git-checkout`
that tracks another branch, this variable tells git to set
up pull to rebase instead of merge (see "branch.<name>.rebase").
When `never`, rebase is never automatically set to true.
When `local`, rebase is set to true for tracked branches of
other local branches.
When `remote`, rebase is set to true for tracked branches of
remote branches.
When `always`, rebase will be set to true for all tracking
branches.
See "branch.autosetupmerge" for details on how to set up a
branch to track another branch.
This option defaults to never.
branch.<name>.remote::
When in branch <name>, it tells `git fetch` which remote to fetch.
If this option is not given, `git fetch` defaults to remote "origin".
@@ -426,7 +441,8 @@ branch.<name>.mergeoptions::
branch.<name>.rebase::
When true, rebase the branch <name> on top of the fetched branch,
instead of merging the default branch from the default remote.
instead of merging the default branch from the default remote when
"git pull" is run.
*NOTE*: this is a possibly dangerous operation; do *not* use
it unless you understand the implications (see linkgit:git-rebase[1]
for details).
@@ -684,6 +700,36 @@ specified as 'gitcvs.<access_method>.<varname>' (where 'access_method'
is one of "ext" and "pserver") to make them apply only for the given
access method.
gui.commitmsgwidth::
Defines how wide the commit message window is in the
linkgit:git-gui[1]. "75" is the default.
gui.diffcontext::
Specifies how many context lines should be used in calls to diff
made by the linkgit:git-gui[1]. The default is "5".
gui.matchtrackingbranch::
Determines if new branches created with linkgit:git-gui[1] should
default to tracking remote branches with matching names or
not. Default: "false".
gui.newbranchtemplate::
Is used as suggested name when creating new branches using the
linkgit:git-gui[1].
gui.pruneduringfetch::
"true" if linkgit:git-gui[1] should prune tracking branches when
performing a fetch. The default value is "false".
gui.trustmtime::
Determines if linkgit:git-gui[1] should trust the file modification
timestamp or not. By default the timestamps are not trusted.
gui.spellingdictionary::
Specifies the dictionary used for spell checking commit messages in
the linkgit:git-gui[1]. When set to "none" spell checking is turned
off.
help.browser::
Specify the browser that will be used to display help in the
'web' format. See linkgit:git-help[1].
@@ -779,37 +825,16 @@ man.viewer::
Specify the programs that may be used to display help in the
'man' format. See linkgit:git-help[1].
merge.summary::
Whether to include summaries of merged commits in newly created
merge commit messages. False by default.
include::merge-config.txt[]
merge.tool::
Controls which merge resolution program is used by
linkgit:git-mergetool[1]. Valid built-in values are: "kdiff3",
"tkdiff", "meld", "xxdiff", "emerge", "vimdiff", "gvimdiff", and
"opendiff". Any other value is treated is custom merge tool
and there must be a corresponing mergetool.<tool>.cmd option.
man.<tool>.cmd::
Specify the command to invoke the specified man viewer. The
specified command is evaluated in shell with the man page
passed as argument. (See linkgit:git-help[1].)
merge.verbosity::
Controls the amount of output shown by the recursive merge
strategy. Level 0 outputs nothing except a final error
message if conflicts were detected. Level 1 outputs only
conflicts, 2 outputs conflicts and file changes. Level 5 and
above outputs debugging information. The default is level 2.
Can be overridden by 'GIT_MERGE_VERBOSITY' environment variable.
merge.<driver>.name::
Defines a human readable name for a custom low-level
merge driver. See linkgit:gitattributes[5] for details.
merge.<driver>.driver::
Defines the command that implements a custom low-level
merge driver. See linkgit:gitattributes[5] for details.
merge.<driver>.recursive::
Names a low-level merge driver to be used when
performing an internal merge between common ancestors.
See linkgit:gitattributes[5] for details.
man.<tool>.path::
Override the path for the given tool that may be used to
display help in the 'man' format. See linkgit:git-help[1].
mergetool.<tool>.path::
Override the path for the given tool. This is useful in case
@@ -921,6 +946,10 @@ remote.<name>.push::
The default set of "refspec" for linkgit:git-push[1]. See
linkgit:git-push[1].
remote.<name>.mirror::
If true, pushing to this remote will automatically behave
as if the `\--mirror` option was given on the command line.
remote.<name>.skipDefaultUpdate::
If true, this remote will be skipped by default when updating
using the update subcommand of linkgit:git-remote[1].

View File

@@ -137,7 +137,7 @@ Advanced Shared Repository Management
Git allows you to specify scripts called "hooks" to be run at certain
points. You can use these, for example, to send all commits to the shared
repository to a mailing list. See link:hooks.html[Hooks used by git].
repository to a mailing list. See linkgit:githooks[5][Hooks used by git].
You can enforce finer grained permissions using update hooks. See
link:howto/update-hook-example.txt[Controlling access to branches using

View File

@@ -71,7 +71,9 @@ OPTIONS
the specified filepatterns before exiting.
-u::
Update only files that git already knows about. This is similar
Update only files that git already knows about, staging modified
content for commit and marking deleted files for removal. This
is similar
to what "git commit -a" does in preparation for making a commit,
except that the update is limited to paths specified on the
command line. If no paths are specified, all tracked files in the
@@ -98,21 +100,27 @@ those in info/exclude. See link:repository-layout.html[repository layout].
EXAMPLES
--------
git-add Documentation/\\*.txt::
Adds content from all `\*.txt` files under `Documentation`
directory and its subdirectories.
* Adds content from all `\*.txt` files under `Documentation` directory
and its subdirectories:
+
------------
$ git add Documentation/\\*.txt
------------
+
Note that the asterisk `\*` is quoted from the shell in this
example; this lets the command to include the files from
subdirectories of `Documentation/` directory.
git-add git-*.sh::
Considers adding content from all git-*.sh scripts.
Because this example lets shell expand the asterisk
(i.e. you are listing the files explicitly), it does not
consider `subdir/git-foo.sh`.
* Considers adding content from all git-*.sh scripts:
+
------------
$ git add git-*.sh
------------
+
Because this example lets shell expand the asterisk (i.e. you are
listing the files explicitly), it does not consider
`subdir/git-foo.sh`.
Interactive mode
----------------

View File

@@ -85,7 +85,7 @@ Oh, and then after you want to reset to the original head, do a
$ git bisect reset
------------------------------------------------
to get back to the master branch, instead of being in one of the
to get back to the original branch, instead of being in one of the
bisection branches ("git bisect start" will do that for you too,
actually: it will reset the bisection state, and before it does that
it checks that you're not using some old bisection branch).
@@ -224,6 +224,55 @@ tree to the pristine state. Finally the "run" script can exit with
the status of the real test to let "git bisect run" command loop to
know the outcome.
EXAMPLES
--------
* Automatically bisect a broken build between v1.2 and HEAD:
+
------------
$ git bisect start HEAD v1.2 -- # HEAD is bad, v1.2 is good
$ git bisect run make # "make" builds the app
------------
* Automatically bisect a broken test suite:
+
------------
$ cat ~/test.sh
#!/bin/sh
make || exit 125 # this "skip"s broken builds
make test # "make test" runs the test suite
$ git bisect start v1.3 v1.1 -- # v1.3 is bad, v1.1 is good
$ git bisect run ~/test.sh
------------
+
Here we use a "test.sh" custom script. In this script, if "make"
fails, we "skip" the current commit.
+
It's safer to use a custom script outside the repo to prevent
interactions between the bisect, make and test processes and the
script.
+
And "make test" should "exit 0", if the test suite passes, and
"exit 1" (for example) otherwise.
* Automatically bisect a broken test case:
+
------------
$ cat ~/test.sh
#!/bin/sh
make || exit 125 # this "skip"s broken builds
~/check_test_case.sh # does the test case passes ?
$ git bisect start HEAD HEAD~10 -- # culprit is among the last 10
$ git bisect run ~/test.sh
------------
+
Here "check_test_case.sh" should "exit 0", if the test case passes,
and "exit 1" (for example) otherwise.
+
It's safer if both "test.sh" and "check_test_case.sh" scripts are
outside the repo to prevent interactions between the bisect, make and
test processes and the scripts.
Author
------
Written by Linus Torvalds <torvalds@osdl.org>

View File

@@ -8,7 +8,7 @@ git-branch - List, create, or delete branches
SYNOPSIS
--------
[verse]
'git-branch' [--color | --no-color] [-r | -a]
'git-branch' [--color | --no-color] [-r | -a] [--merged | --no-merged]
[-v [--abbrev=<length> | --no-abbrev]]
[--contains <commit>]
'git-branch' [--track | --no-track] [-l] [-f] <branchname> [<start-point>]
@@ -24,6 +24,8 @@ and option `-a` shows both.
With `--contains <commit>`, shows only the branches that
contains the named commit (in other words, the branches whose
tip commits are descendant of the named commit).
With `--merged`, only branches merged into HEAD will be listed, and
with `--no-merged` only branches not merged into HEAD will be listed.
In its second form, a new branch named <branchname> will be created.
It will start out with a head equal to the one given as <start-point>.
@@ -118,6 +120,15 @@ OPTIONS
--no-track::
Ignore the branch.autosetupmerge configuration variable.
--contains <commit>::
Only list branches which contain the specified commit.
--merged::
Only list branches which are fully contained by HEAD.
--no-merged::
Do not list branches which are fully contained by HEAD.
<branchname>::
The name of the branch to create or delete.
The new branch name must pass all checks defined by
@@ -175,6 +186,18 @@ If you are creating a branch that you want to immediately checkout, it's
easier to use the git checkout command with its `-b` option to create
a branch and check it out with a single command.
The options `--contains`, `--merged` and `--no-merged` serves three related
but different purposes:
- `--contains <commit>` is used to find all branches which will need
special attention if <commit> were to be rebased or amended, since those
branches contain the specified <commit>.
- `--merged` is used to find all branches which can be safely deleted,
since those branches are fully contained by HEAD.
- `--no-merged` is used to find branches which are candidates for merging
into HEAD, since those branches are not fully contained by HEAD.
Author
------

View File

@@ -7,7 +7,7 @@ git-cherry-pick - Apply the change introduced by an existing commit
SYNOPSIS
--------
'git-cherry-pick' [--edit] [-n] [-m parent-number] [-x] <commit>
'git-cherry-pick' [--edit] [-n] [-m parent-number] [-s] [-x] <commit>
DESCRIPTION
-----------
@@ -64,6 +64,9 @@ OPTIONS
This is useful when cherry-picking more than one commits'
effect to your working tree in a row.
-s|--signoff::
Add Signed-off-by line at the end of the commit message.
Author
------

View File

@@ -87,7 +87,7 @@ OPTIONS
--no-verify::
This option bypasses the pre-commit and commit-msg hooks.
See also link:hooks.html[hooks].
See also linkgit:githooks[5][hooks].
--allow-empty::
Usually recording a commit that has the exact same tree as its
@@ -292,7 +292,7 @@ order).
HOOKS
-----
This command can run `commit-msg`, `prepare-commit-msg`, `pre-commit`,
and `post-commit` hooks. See link:hooks.html[hooks] for more
and `post-commit` hooks. See linkgit:githooks[5][hooks] for more
information.

View File

@@ -13,9 +13,10 @@ SYNOPSIS
DESCRIPTION
-----------
The command finds the most recent tag that is reachable from a
commit, and if the commit itself is pointed at by the tag, shows
the tag. Otherwise, it suffixes the tag name with the number of
additional commits and the abbreviated object name of the commit.
commit. If the tag points to the commit, then only the tag is
shown. Otherwise, it suffixes the tag name with the number of
additional commits on top of the tagged object and the
abbreviated object name of the most recent commit.
OPTIONS

View File

@@ -133,10 +133,16 @@ use "--tag-name-filter cat" to simply update the tags. In this
case, be very careful and make sure you have the old tags
backed up in case the conversion has run afoul.
+
Note that there is currently no support for proper rewriting of
tag objects; in layman terms, if the tag has a message or signature
attached, the rewritten tag won't have it. Sorry. (It is by
definition impossible to preserve signatures at any rate.)
Nearly proper rewriting of tag objects is supported. If the tag has
a message attached, a new tag object will be created with the same message,
author, and timestamp. If the tag has a signature attached, the
signature will be stripped. It is by definition impossible to preserve
signatures. The reason this is "nearly" proper, is because ideally if
the tag did not change (points to the same object, has the same name, etc.)
it should retain any signature. That is not the case, signatures will always
be removed, buyer beware. There is also no support for changing the
author or timestamp (or the tag message for that matter). Tags which point
to other tags will be rewritten to point to the underlying commit.
--subdirectory-filter <directory>::
Only look at the history which touches the given subdirectory.
@@ -177,6 +183,10 @@ or copyright violation) from all commits:
git filter-branch --tree-filter 'rm filename' HEAD
-------------------------------------------------------
However, if the file is absent from the tree of some commit,
a simple `rm filename` will fail for that tree and commit.
Thus you may instead want to use `rm -f filename` as the script.
A significantly faster version:
--------------------------------------------------------------------------
@@ -243,12 +253,12 @@ committed a merge between P1 and P2, it will be propagated properly
and all children of the merge will become merge commits with P1,P2
as their parents instead of the merge commit.
You can rewrite the commit log messages using `--message-filter`. For
You can rewrite the commit log messages using `--msg-filter`. For
example, `git-svn-id` strings in a repository created by `git-svn` can
be removed this way:
-------------------------------------------------------
git filter-branch --message-filter '
git filter-branch --msg-filter '
sed -e "/^git-svn-id:/d"
'
-------------------------------------------------------

View File

@@ -9,8 +9,8 @@ git-fmt-merge-msg - Produce a merge commit message
SYNOPSIS
--------
[verse]
git-fmt-merge-msg [--summary | --no-summary] <$GIT_DIR/FETCH_HEAD
git-fmt-merge-msg [--summary | --no-summary] -F <file>
git-fmt-merge-msg [--log | --no-log] <$GIT_DIR/FETCH_HEAD
git-fmt-merge-msg [--log | --no-log] -F <file>
DESCRIPTION
-----------
@@ -24,15 +24,19 @@ automatically invoking `git-merge`.
OPTIONS
-------
--summary::
--log::
In addition to branch names, populate the log message with
one-line descriptions from the actual commits that are being
merged.
--no-summary::
--no-log::
Do not list one-line descriptions from the actual commits being
merged.
--summary,--no-summary::
Synonyms to --log and --no-log; these are deprecated and will be
removed in the future.
--file <file>, -F <file>::
Take the list of merged objects from <file> instead of
stdin.
@@ -40,10 +44,14 @@ OPTIONS
CONFIGURATION
-------------
merge.summary::
merge.log::
Whether to include summaries of merged commits in newly
merge commit messages. False by default.
merge.summary::
Synonym to `merge.log`; this is deprecated and will be removed in
the future.
SEE ALSO
--------
linkgit:git-merge[1]

View File

@@ -156,6 +156,12 @@ want a filename like `0001-description-of-my-change.patch`, and
the first letter does not have to be a dot. Leaving it empty would
not add any suffix.
--no-binary::
Don't output contents of changes in binary files, just take note
that they differ. Note that this disable the patch to be properly
applied. By default the contents of changes in those files are
encoded in the patch.
CONFIGURATION
-------------
You can specify extra mail header lines to be added to each message
@@ -168,38 +174,54 @@ and file suffix, and number patches when outputting more than one.
subjectprefix = CHANGE
suffix = .txt
numbered = auto
cc = <email>
------------
EXAMPLES
--------
git-format-patch -k --stdout R1..R2 | git-am -3 -k::
Extract commits between revisions R1 and R2, and apply
them on top of the current branch using `git-am` to
cherry-pick them.
* Extract commits between revisions R1 and R2, and apply them on top of
the current branch using `git-am` to cherry-pick them:
+
------------
$ git format-patch -k --stdout R1..R2 | git-am -3 -k
------------
git-format-patch origin::
Extract all commits which are in the current branch but
not in the origin branch. For each commit a separate file
is created in the current directory.
* Extract all commits which are in the current branch but not in the
origin branch:
+
------------
$ git format-patch origin
------------
+
For each commit a separate file is created in the current directory.
git-format-patch \--root origin::
Extract all commits that lead to 'origin' since the
inception of the project.
* Extract all commits that lead to 'origin' since the inception of the
project:
+
------------
$ git format-patch \--root origin
------------
git-format-patch -M -B origin::
The same as the previous one. Additionally, it detects
and handles renames and complete rewrites intelligently to
produce a renaming patch. A renaming patch reduces the
amount of text output, and generally makes it easier to
review it. Note that the "patch" program does not
understand renaming patches, so use it only when you know
the recipient uses git to apply your patch.
* The same as the previous one:
+
------------
$ git format-patch -M -B origin
------------
+
Additionally, it detects and handles renames and complete rewrites
intelligently to produce a renaming patch. A renaming patch reduces
the amount of text output, and generally makes it easier to review it.
Note that the "patch" program does not understand renaming patches, so
use it only when you know the recipient uses git to apply your patch.
git-format-patch -3::
Extract three topmost commits from the current branch
and format them as e-mailable patches.
* Extract three topmost commits from the current branch and format them
as e-mailable patches:
+
------------
$ git format-patch -3
------------
See Also
--------

View File

@@ -82,28 +82,75 @@ man.viewer
~~~~~~~~~~
The 'man.viewer' config variable will be checked if the 'man' format
is chosen. Only the following values are currently supported:
is chosen. The following values are currently supported:
* "man": use the 'man' program as usual,
* "woman": use 'emacsclient' to launch the "woman" mode in emacs
(this only works starting with emacsclient versions 22),
* "konqueror": use a man KIO slave in konqueror.
* "konqueror": use 'kfmclient' to open the man page in a new konqueror
tab (see 'Note about konqueror' below).
Multiple values may be given to this configuration variable. Their
corresponding programs will be tried in the order listed in the
configuration file.
Values for other tools can be used if there is a corresponding
'man.<tool>.cmd' configuration entry (see below).
Multiple values may be given to the 'man.viewer' configuration
variable. Their corresponding programs will be tried in the order
listed in the configuration file.
For example, this configuration:
------------------------------------------------
[man]
viewer = konqueror
viewer = woman
------------------------------------------------
will try to use konqueror first. But this may fail (for example if
DISPLAY is not set) and in that case emacs' woman mode will be tried.
If everything fails the 'man' program will be tried anyway.
man.<tool>.path
~~~~~~~~~~~~~~~
You can explicitly provide a full path to your preferred man viewer by
setting the configuration variable 'man.<tool>.path'. For example, you
can configure the absolute path to konqueror by setting
'man.konqueror.path'. Otherwise, 'git help' assumes the tool is
available in PATH.
man.<tool>.cmd
~~~~~~~~~~~~~~
When the man viewer, specified by the 'man.viewer' configuration
variables, is not among the supported ones, then the corresponding
'man.<tool>.cmd' configuration variable will be looked up. If this
variable exists then the specified tool will be treated as a custom
command and a shell eval will be used to run the command with the man
page passed as arguments.
Note about konqueror
~~~~~~~~~~~~~~~~~~~~
When 'konqueror' is specified in the 'man.viewer' configuration
variable, we launch 'kfmclient' to try to open the man page on an
already opened konqueror in a new tab if possible.
For consistency, we also try such a trick if 'man.konqueror.path' is
set to something like 'A_PATH_TO/konqueror'. That means we will try to
launch 'A_PATH_TO/kfmclient' instead.
If you really want to use 'konqueror', then you can use something like
the following:
------------------------------------------------
[man]
viewer = konq
[man "konq"]
cmd = A_PATH_TO/konqueror
------------------------------------------------
Note about git config --global
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@@ -9,7 +9,7 @@ git-merge - Join two or more development histories together
SYNOPSIS
--------
[verse]
'git-merge' [-n] [--summary] [--no-commit] [--squash] [-s <strategy>]...
'git-merge' [-n] [--stat] [--no-commit] [--squash] [-s <strategy>]...
[-m <msg>] <remote> <remote>...
'git-merge' <msg> HEAD <remote>...
@@ -46,18 +46,7 @@ linkgit:git-reset[1].
CONFIGURATION
-------------
merge.summary::
Whether to include summaries of merged commits in newly
created merge commit. False by default.
merge.verbosity::
Controls the amount of output shown by the recursive merge
strategy. Level 0 outputs nothing except a final error
message if conflicts were detected. Level 1 outputs only
conflicts, 2 outputs conflicts and file changes. Level 5 and
above outputs debugging information. The default is level 2.
Can be overridden by 'GIT_MERGE_VERBOSITY' environment variable.
include::merge-config.txt[]
branch.<name>.mergeoptions::
Sets default options for merging into branch <name>. The syntax and

View File

@@ -18,12 +18,15 @@ git-prune. See the section "NOTES", below.
This runs `git-fsck --unreachable` using all the refs
available in `$GIT_DIR/refs`, optionally with additional set of
objects specified on the command line, and prunes all
objects specified on the command line, and prunes all unpacked
objects unreachable from any of these head objects from the object database.
In addition, it
prunes the unpacked objects that are also found in packs by
running `git prune-packed`.
Note that unreachable, packed objects will remain. If this is
not desired, see linkgit:git-repack[1].
OPTIONS
-------

View File

@@ -111,40 +111,58 @@ rules apply:
EXAMPLES
--------
git pull, git pull origin::
Update the remote-tracking branches for the repository
you cloned from, then merge one of them into your
current branch. Normally the branch merged in is
the HEAD of the remote repository, but the choice is
determined by the branch.<name>.remote and
branch.<name>.merge options; see linkgit:git-config[1]
for details.
* Update the remote-tracking branches for the repository
you cloned from, then merge one of them into your
current branch:
+
------------------------------------------------
$ git pull, git pull origin
------------------------------------------------
+
Normally the branch merged in is the HEAD of the remote repository,
but the choice is determined by the branch.<name>.remote and
branch.<name>.merge options; see linkgit:git-config[1] for details.
git pull origin next::
Merge into the current branch the remote branch `next`;
leaves a copy of `next` temporarily in FETCH_HEAD, but
does not update any remote-tracking branches.
* Merge into the current branch the remote branch `next`:
+
------------------------------------------------
$ git pull origin next
------------------------------------------------
+
This leaves a copy of `next` temporarily in FETCH_HEAD, but
does not update any remote-tracking branches.
git pull . fixes enhancements::
Bundle local branch `fixes` and `enhancements` on top of
the current branch, making an Octopus merge. This `git pull .`
syntax is equivalent to `git merge`.
* Bundle local branch `fixes` and `enhancements` on top of
the current branch, making an Octopus merge:
+
------------------------------------------------
$ git pull . fixes enhancements
------------------------------------------------
+
This `git pull .` syntax is equivalent to `git merge`.
git pull -s ours . obsolete::
Merge local branch `obsolete` into the current branch,
using `ours` merge strategy.
* Merge local branch `obsolete` into the current branch, using `ours`
merge strategy:
+
------------------------------------------------
$ git pull -s ours . obsolete
------------------------------------------------
git pull --no-commit . maint::
Merge local branch `maint` into the current branch, but
do not make a commit automatically. This can be used
when you want to include further changes to the merge,
or want to write your own merge commit message.
* Merge local branch `maint` into the current branch, but do not make
a commit automatically:
+
------------------------------------------------
$ git pull --no-commit . maint
------------------------------------------------
+
This can be used when you want to include further changes to the
merge, or want to write your own merge commit message.
+
You should refrain from abusing this option to sneak substantial
changes into a merge commit. Small fixups like bumping
release/version name would be acceptable.
Command line pull of multiple branches from one repository::
* Command line pull of multiple branches from one repository:
+
------------------------------------------------
$ git checkout master
@@ -152,12 +170,12 @@ $ git fetch origin +pu:pu maint:tmp
$ git pull . tmp
------------------------------------------------
+
This updates (or creates, as necessary) branches `pu` and `tmp`
in the local repository by fetching from the branches
(respectively) `pu` and `maint` from the remote repository.
This updates (or creates, as necessary) branches `pu` and `tmp` in
the local repository by fetching from the branches (respectively)
`pu` and `maint` from the remote repository.
+
The `pu` branch will be updated even if it is does not
fast-forward; the others will not be.
The `pu` branch will be updated even if it is does not fast-forward;
the others will not be.
+
The final command then merges the newly fetched `tmp` into master.

View File

@@ -70,7 +70,9 @@ the remote repository.
be mirrored to the remote repository. Newly created local
refs will be pushed to the remote end, locally updated refs
will be force updated on the remote end, and deleted refs
will be removed from the remote end.
will be removed from the remote end. This is the default
if the configuration option `remote.<remote>.mirror` is
set.
\--dry-run::
Do everything except actually send the updates.

View File

@@ -47,9 +47,11 @@ 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.
+
In mirror mode, enabled with `--mirror`, the refs will not be stored
In mirror mode, enabled with `\--mirror`, the refs will not be stored
in the 'refs/remotes/' namespace, but in 'refs/heads/'. This option
only makes sense in bare repositories.
only makes sense in bare repositories. If a remote uses mirror
mode, furthermore, `git push` will always behave as if `\--mirror`
was passed.
'rm'::

View File

@@ -347,7 +347,7 @@ Each line of options has this format:
* Use `*` to mean that this option should not be listed in the usage
generated for the `-h` argument. It's shown for `--help-all` as
documented in linkgit:gitcli[5].
documented in linkgit:gitcli[7].
* Use `!` to not make the corresponding negated long option available.

View File

@@ -7,7 +7,7 @@ git-revert - Revert an existing commit
SYNOPSIS
--------
'git-revert' [--edit | --no-edit] [-n] [-m parent-number] <commit>
'git-revert' [--edit | --no-edit] [-n] [-m parent-number] [-s] <commit>
DESCRIPTION
-----------
@@ -51,6 +51,9 @@ OPTIONS
This is useful when reverting more than one commits'
effect to your working tree in a row.
-s|--signoff::
Add Signed-off-by line at the end of the commit message.
Author
------

View File

@@ -11,7 +11,8 @@ SYNOPSIS
[verse]
'git-submodule' [--quiet] add [-b branch] [--] <repository> [<path>]
'git-submodule' [--quiet] status [--cached] [--] [<path>...]
'git-submodule' [--quiet] [init|update] [--] [<path>...]
'git-submodule' [--quiet] init [--] [<path>...]
'git-submodule' [--quiet] update [--init] [--] [<path>...]
'git-submodule' [--quiet] summary [--summary-limit <n>] [commit] [--] [<path>...]
@@ -47,6 +48,10 @@ update::
Update the registered submodules, i.e. clone missing submodules and
checkout the commit specified in the index of the containing repository.
This will make the submodules HEAD be detached.
+
If the submodule is not yet initialized, and you just want to use the
setting as stored in .gitmodules, you can automatically initialize the
submodule with the --init option.
summary::
Show commit summary between the given commit (defaults to HEAD) and

View File

@@ -166,11 +166,18 @@ environment). This command has the same behaviour.
Any other arguments are passed directly to `git log'
'blame'::
Show what revision and author last modified each line of a file. This is
identical to `git blame', but SVN revision numbers are shown instead of git
commit hashes.
Show what revision and author last modified each line of a file. The
output of this mode is format-compatible with the output of
`svn blame' by default. Like the SVN blame command,
local uncommitted changes in the working copy are ignored;
the version of the file in the HEAD revision is annotated. Unknown
arguments are passed directly to git-blame.
+
All arguments are passed directly to `git blame'.
--git-format;;
Produce output in the same format as `git blame', but with
SVN revision numbers instead of git commit hashes. In this mode,
changes that haven't been committed to SVN (including local
working-copy edits) are shown as revision 0.
--
'find-rev'::
@@ -188,6 +195,12 @@ All arguments are passed directly to `git blame'.
commit. All merging is assumed to have taken place
independently of git-svn functions.
'create-ignore'::
Recursively finds the svn:ignore property on directories and
creates matching .gitignore files. The resulting files are staged to
be committed, but are not committed.
'show-ignore'::
Recursively finds and lists the svn:ignore property on
directories. The output is suitable for appending to

View File

@@ -20,7 +20,7 @@ The following browsers (or commands) are currently supported:
* firefox (this is the default under X Window when not using KDE)
* iceweasel
* konqueror (this is the default under KDE)
* konqueror (this is the default under KDE, see 'Note about konqueror' below)
* w3m (this is the default outside graphical environments)
* links
* lynx
@@ -71,6 +71,28 @@ variable exists then "git web--browse" will treat the specified tool
as a custom command and will use a shell eval to run the command with
the URLs passed as arguments.
Note about konqueror
--------------------
When 'konqueror' is specified by the a command line option or a
configuration variable, we launch 'kfmclient' to try to open the HTML
man page on an already opened konqueror in a new tab if possible.
For consistency, we also try such a trick if 'browser.konqueror.path' is
set to something like 'A_PATH_TO/konqueror'. That means we will try to
launch 'A_PATH_TO/kfmclient' instead.
If you really want to use 'konqueror', then you can use something like
the following:
------------------------------------------------
[web]
browser = konq
[browser "konq"]
cmd = A_PATH_TO/konqueror
------------------------------------------------
Note about git config --global
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@@ -364,7 +364,7 @@ File/Directory Structure
Please see the link:repository-layout.html[repository layout] document.
Read link:hooks.html[hooks] for more details about each hook.
Read linkgit:githooks[5][hooks] for more details about each hook.
Higher level SCMs may provide and manage additional information in the
`$GIT_DIR`.

View File

@@ -1,4 +1,4 @@
gitcli(5)
gitcli(7)
=========
NAME

View File

@@ -1,5 +1,17 @@
Hooks used by git
=================
githooks(5)
===========
NAME
----
githooks - Hooks used by git
SYNOPSIS
--------
$GIT_DIR/hooks/*
DESCRIPTION
-----------
Hooks are little scripts you can place in `$GIT_DIR/hooks`
directory to trigger action at certain points. When
@@ -28,10 +40,11 @@ The default 'applypatch-msg' hook, when enabled, runs the
pre-applypatch
--------------
This hook is invoked by `git-am`. It takes no parameter,
and is invoked after the patch is applied, but before a commit
is made. Exiting with non-zero status causes the working tree
after application of the patch not committed.
This hook is invoked by `git-am`. It takes no parameter, and is
invoked after the patch is applied, but before a commit is made.
If it exits with non-zero status, then the working tree will not be
committed after applying the patch.
It can be used to inspect the current working tree and refuse to
make a commit if it does not pass certain test.
@@ -136,7 +149,8 @@ post-merge
This hook is invoked by `git-merge`, which happens when a `git pull`
is done on a local repository. The hook takes a single parameter, a status
flag specifying whether or not the merge being done was a squash merge.
This hook cannot affect the outcome of `git-merge`.
This hook cannot affect the outcome of `git-merge` and is not executed,
if the merge failed due to conflicts.
This hook can be used in conjunction with a corresponding pre-commit hook to
save and restore any form of metadata associated with the working tree
@@ -283,3 +297,7 @@ pre-auto-gc
This hook is invoked by `git-gc --auto`. It takes no parameter, and
exiting with non-zero status from this script causes the `git-gc --auto`
to abort.
GIT
---
Part of the linkgit:git[7] suite

View File

@@ -0,0 +1,40 @@
merge.stat::
Whether to print the diffstat berween ORIG_HEAD and merge result
at the end of the merge. True by default.
merge.log::
Whether to include summaries of merged commits in newly created
merge commit messages. False by default.
merge.renameLimit::
The number of files to consider when performing rename detection
during a merge; if not specified, defaults to the value of
diff.renameLimit.
merge.tool::
Controls which merge resolution program is used by
linkgit:git-mergetool[1]. Valid built-in values are: "kdiff3",
"tkdiff", "meld", "xxdiff", "emerge", "vimdiff", "gvimdiff", and
"opendiff". Any other value is treated is custom merge tool
and there must be a corresponing mergetool.<tool>.cmd option.
merge.verbosity::
Controls the amount of output shown by the recursive merge
strategy. Level 0 outputs nothing except a final error
message if conflicts were detected. Level 1 outputs only
conflicts, 2 outputs conflicts and file changes. Level 5 and
above outputs debugging information. The default is level 2.
Can be overridden by 'GIT_MERGE_VERBOSITY' environment variable.
merge.<driver>.name::
Defines a human readable name for a custom low-level
merge driver. See linkgit:gitattributes[5] for details.
merge.<driver>.driver::
Defines the command that implements a custom low-level
merge driver. See linkgit:gitattributes[5] for details.
merge.<driver>.recursive::
Names a low-level merge driver to be used when
performing an internal merge between common ancestors.
See linkgit:gitattributes[5] for details.

View File

@@ -1,10 +1,23 @@
--summary::
--stat::
Show a diffstat at the end of the merge. The diffstat is also
controlled by the configuration option merge.diffstat.
controlled by the configuration option merge.stat.
-n, \--no-summary::
-n, \--no-stat::
Do not show diffstat at the end of the merge.
--summary, \--no-summary::
Synonyms to --stat and --no-stat; these are deprecated and will be
removed in the future.
--log::
In addition to branch names, populate the log message with
one-line descriptions from the actual commits that are being
merged.
--no-log::
Do not list one-line descriptions from the actual commits being
merged.
--no-commit::
Perform the merge but pretend the merge failed and do
not autocommit, to give the user a chance to inspect and

View File

@@ -3,7 +3,10 @@ git repository layout
You may find these things in your git repository (`.git`
directory for a repository associated with your working tree, or
`'project'.git` directory for a public 'bare' repository).
`'project'.git` directory for a public 'bare' repository. It is
also possible to have a working tree where `.git` is a plain
ascii file containing `gitdir: <path>`, i.e. the path to the
real git repository).
objects::
Object store associated with this repository. Usually
@@ -121,7 +124,7 @@ hooks::
commands. A handful of sample hooks are installed when
`git init` is run, but all of them are disabled by
default. To enable, they need to be made executable.
Read link:hooks.html[hooks] for more details about
Read linkgit:githooks[5][hooks] for more details about
each hook.
index::

View File

@@ -1881,7 +1881,7 @@ $ chmod a+x hooks/post-update
(For an explanation of the last two lines, see
linkgit:git-update-server-info[1], and the documentation
link:hooks.html[Hooks used by git].)
linkgit:githooks[5][Hooks used by git].)
Advertise the URL of proj.git. Anybody else should then be able to
clone or pull from that URL, for example with a command line like:

View File

@@ -11,7 +11,7 @@ LF='
if test -f version
then
VN=$(cat version) || VN="$DEF_VER"
elif test -d .git &&
elif test -d .git -o -f .git &&
VN=$(git describe --abbrev=4 HEAD 2>/dev/null) &&
case "$VN" in
*$LF*) (exit 1) ;;

View File

@@ -38,6 +38,10 @@ Issues of note:
has been actively developed since 1997, and people have moved over to
graphical file managers.
NOTE: As of gnuit-4.9.2, the GNU interactive tools package has been
renamed. You can compile gnuit with the --disable-transition
option and then it will not conflict with git.
- You can use git after building but without installing if you
wanted to. Various git commands need to find other git
commands and scripts to do their work, so you would need to

View File

@@ -422,6 +422,7 @@ LIB_OBJS += log-tree.o
LIB_OBJS += mailmap.o
LIB_OBJS += match-trees.o
LIB_OBJS += merge-file.o
LIB_OBJS += name-hash.o
LIB_OBJS += object.o
LIB_OBJS += pack-check.o
LIB_OBJS += pack-revindex.o
@@ -634,8 +635,12 @@ endif
ifeq ($(uname_S),AIX)
NO_STRCASESTR=YesPlease
NO_MEMMEM = YesPlease
NO_MKDTEMP = YesPlease
NO_STRLCPY = YesPlease
FREAD_READS_DIRECTORIES = UnfortunatelyYes
INTERNAL_QSORT = UnfortunatelyYes
NEEDS_LIBICONV=YesPlease
BASIC_CFLAGS += -D_LARGE_FILES
endif
ifeq ($(uname_S),GNU)
# GNU/Hurd

View File

@@ -32,6 +32,21 @@ static int find_tracked_branch(struct remote *remote, void *priv)
return 0;
}
static int should_setup_rebase(const struct tracking *tracking)
{
switch (autorebase) {
case AUTOREBASE_NEVER:
return 0;
case AUTOREBASE_LOCAL:
return tracking->remote == NULL;
case AUTOREBASE_REMOTE:
return tracking->remote != NULL;
case AUTOREBASE_ALWAYS:
return 1;
}
return 0;
}
/*
* This is called when new_ref is branched off of orig_ref, and tries
* to infer the settings for branch.<new_ref>.{remote,merge} from the
@@ -69,9 +84,14 @@ static int setup_tracking(const char *new_ref, const char *orig_ref,
git_config_set(key, tracking.remote ? tracking.remote : ".");
sprintf(key, "branch.%s.merge", new_ref);
git_config_set(key, tracking.src ? tracking.src : orig_ref);
free(tracking.src);
printf("Branch %s set up to track %s branch %s.\n", new_ref,
tracking.remote ? "remote" : "local", orig_ref);
if (should_setup_rebase(&tracking)) {
sprintf(key, "branch.%s.rebase", new_ref);
git_config_set(key, "true");
printf("This branch will rebase on pull.\n");
}
free(tracking.src);
return 0;
}

View File

@@ -2247,7 +2247,7 @@ static int check_to_create_blob(const char *new_name, int ok_if_exists)
* In such a case, path "new_name" does not exist as
* far as git is concerned.
*/
if (has_symlink_leading_path(new_name, NULL))
if (has_symlink_leading_path(strlen(new_name), new_name))
return 0;
return error("%s: already exists in working directory", new_name);

View File

@@ -15,7 +15,7 @@
#include "branch.h"
static const char * const builtin_branch_usage[] = {
"git-branch [options] [-r | -a]",
"git-branch [options] [-r | -a] [--merged | --no-merged]",
"git-branch [options] [-l] [-f] <branchname> [<start-point>]",
"git-branch [options] [-r] (-d | -D) <branchname>",
"git-branch [options] (-m | -M) [<oldbranch>] <newbranch>",
@@ -46,6 +46,8 @@ enum color_branch {
COLOR_BRANCH_CURRENT = 4,
};
static int mergefilter = -1;
static int parse_branch_color_slot(const char *var, int ofs)
{
if (!strcasecmp(var+ofs, "plain"))
@@ -210,6 +212,7 @@ static int append_ref(const char *refname, const unsigned char *sha1, int flags,
struct ref_item *newitem;
int kind = REF_UNKNOWN_TYPE;
int len;
static struct commit_list branch;
/* Detect kind */
if (!prefixcmp(refname, "refs/heads/")) {
@@ -231,6 +234,16 @@ static int append_ref(const char *refname, const unsigned char *sha1, int flags,
if ((kind & ref_list->kinds) == 0)
return 0;
if (mergefilter > -1) {
branch.item = lookup_commit_reference_gently(sha1, 1);
if (!branch.item)
die("Unable to lookup tip of branch %s", refname);
if (mergefilter == 0 && has_commit(head_sha1, &branch))
return 0;
if (mergefilter == 1 && !has_commit(head_sha1, &branch))
return 0;
}
/* Resize buffer */
if (ref_list->index >= ref_list->alloc) {
ref_list->alloc = alloc_nr(ref_list->alloc);
@@ -444,6 +457,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
OPT_BIT('M', NULL, &rename, "move/rename a branch, even if target exists", 2),
OPT_BOOLEAN('l', NULL, &reflog, "create the branch's reflog"),
OPT_BOOLEAN('f', NULL, &force_create, "force creation (when already exists)"),
OPT_SET_INT(0, "merged", &mergefilter, "list only merged branches", 1),
OPT_END(),
};

View File

@@ -142,7 +142,7 @@ static void describe_detached_head(char *msg, struct commit *commit)
struct strbuf sb;
strbuf_init(&sb, 0);
parse_commit(commit);
pretty_print_commit(CMIT_FMT_ONELINE, commit, &sb, 0, "", "", 0, 0);
pretty_print_commit(CMIT_FMT_ONELINE, commit, &sb, 0, NULL, NULL, 0, 0);
fprintf(stderr, "%s %s... %s\n", msg,
find_unique_abbrev(commit->object.sha1, DEFAULT_ABBREV), sb.buf);
strbuf_release(&sb);

View File

@@ -47,6 +47,7 @@ static enum {
static char *logfile, *force_author, *template_file;
static char *edit_message, *use_message;
static char *author_name, *author_email, *author_date;
static int all, edit_flag, also, interactive, only, amend, signoff;
static int quiet, verbose, untracked_files, no_verify, allow_empty;
/*
@@ -101,7 +102,7 @@ static struct option builtin_commit_options[] = {
OPT_BOOLEAN('o', "only", &only, "commit only specified files"),
OPT_BOOLEAN('n', "no-verify", &no_verify, "bypass pre-commit hook"),
OPT_BOOLEAN(0, "amend", &amend, "amend previous commit"),
OPT_BOOLEAN(0, "untracked-files", &untracked_files, "show all untracked files"),
OPT_BOOLEAN('u', "untracked-files", &untracked_files, "show all untracked files"),
OPT_BOOLEAN(0, "allow-empty", &allow_empty, "ok to record an empty change"),
OPT_STRING(0, "cleanup", &cleanup_arg, "default", "how to strip spaces and #comments from message"),
@@ -175,9 +176,11 @@ static void add_remove_files(struct path_list *list)
{
int i;
for (i = 0; i < list->nr; i++) {
struct stat st;
struct path_list_item *p = &(list->items[i]);
if (file_exists(p->path))
add_file_to_cache(p->path, 0);
if (!lstat(p->path, &st))
add_to_cache(p->path, &st, 0);
else
remove_file_from_cache(p->path);
}
@@ -395,6 +398,47 @@ static int is_a_merge(const unsigned char *sha1)
static const char sign_off_header[] = "Signed-off-by: ";
static void determine_author_info(void)
{
char *name, *email, *date;
name = getenv("GIT_AUTHOR_NAME");
email = getenv("GIT_AUTHOR_EMAIL");
date = getenv("GIT_AUTHOR_DATE");
if (use_message) {
const char *a, *lb, *rb, *eol;
a = strstr(use_message_buffer, "\nauthor ");
if (!a)
die("invalid commit: %s", use_message);
lb = strstr(a + 8, " <");
rb = strstr(a + 8, "> ");
eol = strchr(a + 8, '\n');
if (!lb || !rb || !eol)
die("invalid commit: %s", use_message);
name = xstrndup(a + 8, lb - (a + 8));
email = xstrndup(lb + 2, rb - (lb + 2));
date = xstrndup(rb + 2, eol - (rb + 2));
}
if (force_author) {
const char *lb = strstr(force_author, " <");
const char *rb = strchr(force_author, '>');
if (!lb || !rb)
die("malformed --author parameter");
name = xstrndup(force_author, lb - force_author);
email = xstrndup(lb + 2, rb - (lb + 2));
}
author_name = name;
author_email = email;
author_date = date;
}
static int prepare_to_commit(const char *index_file, const char *prefix)
{
struct stat statbuf;
@@ -404,6 +448,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix)
FILE *fp;
const char *hook_arg1 = NULL;
const char *hook_arg2 = NULL;
int ident_shown = 0;
if (!no_verify && run_hook(index_file, "pre-commit", NULL))
return 0;
@@ -483,7 +528,14 @@ static int prepare_to_commit(const char *index_file, const char *prefix)
strbuf_release(&sb);
determine_author_info();
/* This checks if committer ident is explicitly given */
git_committer_info(0);
if (use_editor) {
char *author_ident;
const char *committer_ident;
if (in_merge)
fprintf(fp,
"#\n"
@@ -506,6 +558,27 @@ static int prepare_to_commit(const char *index_file, const char *prefix)
if (only_include_assumed)
fprintf(fp, "# %s\n", only_include_assumed);
author_ident = xstrdup(fmt_name(author_name, author_email));
committer_ident = fmt_name(getenv("GIT_COMMITTER_NAME"),
getenv("GIT_COMMITTER_EMAIL"));
if (strcmp(author_ident, committer_ident))
fprintf(fp,
"%s"
"# Author: %s\n",
ident_shown++ ? "" : "#\n",
author_ident);
free(author_ident);
if (!user_ident_explicitly_given)
fprintf(fp,
"%s"
"# Committer: %s\n",
ident_shown++ ? "" : "#\n",
committer_ident);
if (ident_shown)
fprintf(fp, "#\n");
saved_color_setting = wt_status_use_color;
wt_status_use_color = 0;
commitable = run_status(fp, index_file, prefix, 1);
@@ -622,45 +695,6 @@ static int message_is_empty(struct strbuf *sb, int start)
return 1;
}
static void determine_author_info(struct strbuf *sb)
{
char *name, *email, *date;
name = getenv("GIT_AUTHOR_NAME");
email = getenv("GIT_AUTHOR_EMAIL");
date = getenv("GIT_AUTHOR_DATE");
if (use_message) {
const char *a, *lb, *rb, *eol;
a = strstr(use_message_buffer, "\nauthor ");
if (!a)
die("invalid commit: %s", use_message);
lb = strstr(a + 8, " <");
rb = strstr(a + 8, "> ");
eol = strchr(a + 8, '\n');
if (!lb || !rb || !eol)
die("invalid commit: %s", use_message);
name = xstrndup(a + 8, lb - (a + 8));
email = xstrndup(lb + 2, rb - (lb + 2));
date = xstrndup(rb + 2, eol - (rb + 2));
}
if (force_author) {
const char *lb = strstr(force_author, " <");
const char *rb = strchr(force_author, '>');
if (!lb || !rb)
die("malformed --author parameter");
name = xstrndup(force_author, lb - force_author);
email = xstrndup(lb + 2, rb - (lb + 2));
}
strbuf_addf(sb, "author %s\n", fmt_ident(name, email, date, IDENT_ERROR_ON_NO_NAME));
}
static int parse_and_validate_options(int argc, const char *argv[],
const char * const usage[])
{
@@ -920,7 +954,8 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
strbuf_addf(&sb, "parent %s\n", sha1_to_hex(head_sha1));
}
determine_author_info(&sb);
strbuf_addf(&sb, "author %s\n",
fmt_ident(author_name, author_email, author_date, IDENT_ERROR_ON_NO_NAME));
strbuf_addf(&sb, "committer %s\n", git_committer_info(IDENT_ERROR_ON_NO_NAME));
if (!is_encoding_utf8(git_commit_encoding))
strbuf_addf(&sb, "encoding %s\n", git_commit_encoding);

View File

@@ -360,12 +360,10 @@ static int store_updated_refs(const char *url, struct ref *ref_map)
if (ref)
update_local_ref(ref, what, verbose, note);
else if (verbose)
else
sprintf(note, "* %-*s %-*s -> FETCH_HEAD",
SUMMARY_WIDTH, *kind ? kind : "branch",
REFCOL_WIDTH, *what ? what : "HEAD");
else
*note = '\0';
if (*note) {
if (!shown_url) {
fprintf(stderr, "From %.*s\n",
@@ -510,10 +508,8 @@ static void find_non_local_tags(struct transport *transport,
will_fetch(head, ref->old_sha1))) {
path_list_insert(ref_name, &new_refs);
rm = alloc_ref(strlen(ref_name) + 1);
strcpy(rm->name, ref_name);
rm->peer_ref = alloc_ref(strlen(ref_name) + 1);
strcpy(rm->peer_ref->name, ref_name);
rm = alloc_ref_from_str(ref_name);
rm->peer_ref = alloc_ref_from_str(ref_name);
hashcpy(rm->old_sha1, ref_sha1);
**tail = rm;

View File

@@ -6,13 +6,18 @@
#include "tag.h"
static const char *fmt_merge_msg_usage =
"git-fmt-merge-msg [--summary] [--no-summary] [--file <file>]";
"git-fmt-merge-msg [--log] [--no-log] [--file <file>]";
static int merge_summary;
static int fmt_merge_msg_config(const char *key, const char *value)
{
if (!strcmp("merge.summary", key))
static int found_merge_log = 0;
if (!strcmp("merge.log", key)) {
found_merge_log = 1;
merge_summary = git_config_bool(key, value);
}
if (!found_merge_log && !strcmp("merge.summary", key))
merge_summary = git_config_bool(key, value);
return 0;
}
@@ -258,9 +263,10 @@ int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix)
git_config(fmt_merge_msg_config);
while (argc > 1) {
if (!strcmp(argv[1], "--summary"))
if (!strcmp(argv[1], "--log") || !strcmp(argv[1], "--summary"))
merge_summary = 1;
else if (!strcmp(argv[1], "--no-summary"))
else if (!strcmp(argv[1], "--no-log")
|| !strcmp(argv[1], "--no-summary"))
merge_summary = 0;
else if (!strcmp(argv[1], "-F") || !strcmp(argv[1], "--file")) {
if (argc < 3)

View File

@@ -485,6 +485,13 @@ static int git_format_config(const char *var, const char *value)
fmt_patch_suffix = xstrdup(value);
return 0;
}
if (!strcmp(var, "format.cc")) {
if (!value)
return config_error_nonbool(var);
ALLOC_GROW(extra_cc, extra_cc_nr + 1, extra_cc_alloc);
extra_cc[extra_cc_nr++] = xstrdup(value);
return 0;
}
if (!strcmp(var, "diff.color") || !strcmp(var, "color.diff")) {
return 0;
}
@@ -757,6 +764,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
int thread = 0;
int cover_letter = 0;
int boundary_count = 0;
int no_binary_diff = 0;
struct commit *origin = NULL, *head = NULL;
const char *in_reply_to = NULL;
struct patch_ids ids;
@@ -770,7 +778,6 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
rev.diff = 1;
rev.combine_merges = 0;
rev.ignore_merges = 1;
rev.diffopt.msg_sep = "";
DIFF_OPT_SET(&rev.diffopt, RECURSIVE);
rev.subject_prefix = fmt_patch_subject_prefix;
@@ -863,6 +870,8 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
fmt_patch_suffix = argv[i] + 9;
else if (!strcmp(argv[i], "--cover-letter"))
cover_letter = 1;
else if (!strcmp(argv[i], "--no-binary"))
no_binary_diff = 1;
else
argv[j++] = argv[i];
}
@@ -915,7 +924,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
if (!rev.diffopt.output_format)
rev.diffopt.output_format = DIFF_FORMAT_DIFFSTAT | DIFF_FORMAT_SUMMARY | DIFF_FORMAT_PATCH;
if (!DIFF_OPT_TST(&rev.diffopt, TEXT))
if (!DIFF_OPT_TST(&rev.diffopt, TEXT) && !no_binary_diff)
DIFF_OPT_SET(&rev.diffopt, BINARY);
if (!output_directory && !use_stdout)

View File

@@ -92,7 +92,8 @@ static struct path_list current_directory_set = {NULL, 0, 0, 1};
static int call_depth = 0;
static int verbosity = 2;
static int rename_limit = -1;
static int diff_rename_limit = -1;
static int merge_rename_limit = -1;
static int buffer_output = 1;
static struct strbuf obuf = STRBUF_INIT;
@@ -361,7 +362,10 @@ static struct path_list *get_renames(struct tree *tree,
diff_setup(&opts);
DIFF_OPT_SET(&opts, RECURSIVE);
opts.detect_rename = DIFF_DETECT_RENAME;
opts.rename_limit = rename_limit;
opts.rename_limit = merge_rename_limit >= 0 ? merge_rename_limit :
diff_rename_limit >= 0 ? diff_rename_limit :
500;
opts.warn_on_too_large_rename = 1;
opts.output_format = DIFF_FORMAT_NO_OUTPUT;
if (diff_setup_done(&opts) < 0)
die("diff setup failed");
@@ -1343,7 +1347,11 @@ static int merge_config(const char *var, const char *value)
return 0;
}
if (!strcasecmp(var, "diff.renamelimit")) {
rename_limit = git_config_int(var, value);
diff_rename_limit = git_config_int(var, value);
return 0;
}
if (!strcasecmp(var, "merge.renamelimit")) {
merge_rename_limit = git_config_int(var, value);
return 0;
}
return git_default_config(var, value);

View File

@@ -56,6 +56,17 @@ static int do_push(const char *repo, int flags)
if (!remote)
die("bad repository '%s'", repo);
if (remote->mirror)
flags |= (TRANSPORT_PUSH_MIRROR|TRANSPORT_PUSH_FORCE);
if ((flags & (TRANSPORT_PUSH_ALL|TRANSPORT_PUSH_MIRROR)) && refspec)
return -1;
if ((flags & (TRANSPORT_PUSH_ALL|TRANSPORT_PUSH_MIRROR)) ==
(TRANSPORT_PUSH_ALL|TRANSPORT_PUSH_MIRROR)) {
return error("--all and --mirror are incompatible");
}
if (!refspec
&& !(flags & TRANSPORT_PUSH_ALL)
&& remote->push_refspec_nr) {
@@ -95,6 +106,7 @@ int cmd_push(int argc, const char **argv, const char *prefix)
int dry_run = 0;
int force = 0;
int tags = 0;
int rc;
const char *repo = NULL; /* default repository */
struct option options[] = {
@@ -130,14 +142,10 @@ int cmd_push(int argc, const char **argv, const char *prefix)
repo = argv[0];
set_refspecs(argv + 1, argc - 1);
}
if ((flags & (TRANSPORT_PUSH_ALL|TRANSPORT_PUSH_MIRROR)) && refspec)
usage_with_options(push_usage, options);
if ((flags & (TRANSPORT_PUSH_ALL|TRANSPORT_PUSH_MIRROR)) ==
(TRANSPORT_PUSH_ALL|TRANSPORT_PUSH_MIRROR)) {
error("--all and --mirror are incompatible");
rc = do_push(repo, flags);
if (rc == -1)
usage_with_options(push_usage, options);
}
return do_push(repo, flags);
else
return rc;
}

View File

@@ -40,7 +40,7 @@ static int read_cache_unmerged(void)
for (i = 0; i < active_nr; i++) {
struct cache_entry *ce = active_cache[i];
if (ce_stage(ce)) {
remove_index_entry(ce);
remove_name_hash(ce);
if (last && !strcmp(ce->name, last->name))
continue;
cache_tree_invalidate_path(active_cache_tree, ce->name);

View File

@@ -118,6 +118,13 @@ static int add(int argc, const char **argv)
return 1;
}
if (mirror) {
strbuf_reset(&buf);
strbuf_addf(&buf, "remote.%s.mirror", name);
if (git_config_set(buf.buf, "yes"))
return 1;
}
if (fetch && fetch_remote(name))
return 1;

View File

@@ -28,8 +28,6 @@ static int symbolic;
static int abbrev;
static int output_sq;
static int revs_count;
/*
* Some arguments are relevant "revision" arguments,
* others are about output format or other details.
@@ -102,7 +100,6 @@ static void show_rev(int type, const unsigned char *sha1, const char *name)
if (!(filter & DO_REVS))
return;
def = NULL;
revs_count++;
if (type != show_type)
putchar('^');
@@ -150,7 +147,7 @@ static int show_flag(const char *arg)
return 0;
}
static void show_default(void)
static int show_default(void)
{
const char *s = def;
@@ -160,9 +157,10 @@ static void show_default(void)
def = NULL;
if (!get_sha1(s, sha1)) {
show_rev(NORMAL, sha1, s);
return;
return 1;
}
}
return 0;
}
static int show_reference(const char *refname, const unsigned char *sha1, int flag, void *cb_data)
@@ -375,8 +373,9 @@ static void die_no_single_rev(int quiet)
int cmd_rev_parse(int argc, const char **argv, const char *prefix)
{
int i, as_is = 0, verify = 0, quiet = 0;
int i, as_is = 0, verify = 0, quiet = 0, revs_count = 0, type = 0;
unsigned char sha1[20];
const char *name = NULL;
if (argc > 1 && !strcmp("--parseopt", argv[1]))
return cmd_parseopt(argc - 1, argv + 1, prefix);
@@ -568,12 +567,17 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
/* Not a flag argument */
if (try_difference(arg))
continue;
if (!get_sha1(arg, sha1)) {
show_rev(NORMAL, sha1, arg);
continue;
name = arg;
type = NORMAL;
if (*arg == '^') {
name++;
type = REVERSED;
}
if (*arg == '^' && !get_sha1(arg+1, sha1)) {
show_rev(REVERSED, sha1, arg+1);
if (!get_sha1(name, sha1)) {
if (verify)
revs_count++;
else
show_rev(type, sha1, name);
continue;
}
if (verify)
@@ -583,8 +587,14 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
continue;
verify_filename(prefix, arg);
}
show_default();
if (verify && revs_count != 1)
if (verify) {
if (revs_count == 1) {
show_rev(type, sha1, name);
return 0;
} else if (revs_count == 0 && show_default())
return 0;
die_no_single_rev(quiet);
} else
show_default();
return 0;
}

View File

@@ -33,7 +33,7 @@ static const char * const cherry_pick_usage[] = {
NULL
};
static int edit, no_replay, no_commit, mainline;
static int edit, no_replay, no_commit, mainline, signoff;
static enum { REVERT, CHERRY_PICK } action;
static struct commit *commit;
@@ -53,6 +53,7 @@ static void parse_args(int argc, const char **argv)
OPT_BOOLEAN('e', "edit", &edit, "edit the commit message"),
OPT_BOOLEAN('x', NULL, &no_replay, "append commit name when cherry-picking"),
OPT_BOOLEAN('r', NULL, &noop, "no-op (backward compatibility)"),
OPT_BOOLEAN('s', "signoff", &signoff, "add Signed-off-by:"),
OPT_INTEGER('m', "mainline", &mainline, "parent number"),
OPT_END(),
};
@@ -404,10 +405,19 @@ static int revert_or_cherry_pick(int argc, const char **argv)
*/
if (!no_commit) {
if (edit)
return execl_git_cmd("commit", "-n", NULL);
else
return execl_git_cmd("commit", "-n", "-F", defmsg, NULL);
/* 6 is max possible length of our args array including NULL */
const char *args[6];
int i = 0;
args[i++] = "commit";
args[i++] = "-n";
if (signoff)
args[i++] = "-s";
if (!edit) {
args[i++] = "-F";
args[i++] = defmsg;
}
args[i] = NULL;
return execv_git_cmd(args);
}
free(reencoded_message);

52
cache.h
View File

@@ -133,6 +133,7 @@ struct cache_entry {
#define CE_UPDATE (0x10000)
#define CE_REMOVE (0x20000)
#define CE_UPTODATE (0x40000)
#define CE_ADDED (0x80000)
#define CE_HASHED (0x100000)
#define CE_UNHASHED (0x200000)
@@ -153,20 +154,6 @@ static inline void copy_cache_entry(struct cache_entry *dst, struct cache_entry
dst->ce_flags = (dst->ce_flags & ~CE_STATE_MASK) | state;
}
/*
* We don't actually *remove* it, we can just mark it invalid so that
* we won't find it in lookups.
*
* Not only would we have to search the lists (simple enough), but
* we'd also have to rehash other hash buckets in case this makes the
* hash bucket empty (common). So it's much better to just mark
* it.
*/
static inline void remove_index_entry(struct cache_entry *ce)
{
ce->ce_flags |= CE_UNHASHED;
}
static inline unsigned create_ce_flags(size_t len, unsigned stage)
{
if (len >= CE_NAMEMASK)
@@ -241,6 +228,23 @@ struct index_state {
extern struct index_state the_index;
/* Name hashing */
extern void add_name_hash(struct index_state *istate, struct cache_entry *ce);
/*
* We don't actually *remove* it, we can just mark it invalid so that
* we won't find it in lookups.
*
* Not only would we have to search the lists (simple enough), but
* we'd also have to rehash other hash buckets in case this makes the
* hash bucket empty (common). So it's much better to just mark
* it.
*/
static inline void remove_name_hash(struct cache_entry *ce)
{
ce->ce_flags |= CE_UNHASHED;
}
#ifndef NO_THE_INDEX_COMPATIBILITY_MACROS
#define active_cache (the_index.cache)
#define active_nr (the_index.cache_nr)
@@ -257,11 +261,12 @@ extern struct index_state the_index;
#define add_cache_entry(ce, option) add_index_entry(&the_index, (ce), (option))
#define remove_cache_entry_at(pos) remove_index_entry_at(&the_index, (pos))
#define remove_file_from_cache(path) remove_file_from_index(&the_index, (path))
#define add_to_cache(path, st, verbose) add_to_index(&the_index, (path), (st), (verbose))
#define add_file_to_cache(path, verbose) add_file_to_index(&the_index, (path), (verbose))
#define refresh_cache(flags) refresh_index(&the_index, (flags), NULL, NULL)
#define ce_match_stat(ce, st, options) ie_match_stat(&the_index, (ce), (st), (options))
#define ce_modified(ce, st, options) ie_modified(&the_index, (ce), (st), (options))
#define cache_name_exists(name, namelen) index_name_exists(&the_index, (name), (namelen))
#define cache_name_exists(name, namelen, igncase) index_name_exists(&the_index, (name), (namelen), (igncase))
#endif
enum object_type {
@@ -311,6 +316,7 @@ extern char *get_index_file(void);
extern char *get_graft_file(void);
extern int set_git_dir(const char *path);
extern const char *get_git_work_tree(void);
extern const char *read_gitfile_gently(const char *path);
#define ALTERNATE_DB_ENVIRONMENT "GIT_ALTERNATE_OBJECT_DIRECTORIES"
@@ -350,7 +356,7 @@ extern int write_index(const struct index_state *, int newfd);
extern int discard_index(struct index_state *);
extern int unmerged_index(const struct index_state *);
extern int verify_path(const char *path);
extern int index_name_exists(struct index_state *istate, const char *name, int namelen);
extern struct cache_entry *index_name_exists(struct index_state *istate, const char *name, int namelen, int igncase);
extern int index_name_pos(const struct index_state *, const char *name, int namelen);
#define ADD_CACHE_OK_TO_ADD 1 /* Ok to add */
#define ADD_CACHE_OK_TO_REPLACE 2 /* Ok to replace file/directory */
@@ -360,6 +366,7 @@ extern int add_index_entry(struct index_state *, struct cache_entry *ce, int opt
extern struct cache_entry *refresh_cache_entry(struct cache_entry *ce, int really);
extern int remove_index_entry_at(struct index_state *, int pos);
extern int remove_file_from_index(struct index_state *, const char *path);
extern int add_to_index(struct index_state *, const char *path, struct stat *, int verbose);
extern int add_file_to_index(struct index_state *, const char *path, int verbose);
extern struct cache_entry *make_cache_entry(unsigned int mode, const unsigned char *sha1, const char *path, int stage, int refresh);
extern int ce_same_name(struct cache_entry *a, struct cache_entry *b);
@@ -404,6 +411,7 @@ extern int delete_ref(const char *, const unsigned char *sha1);
extern int trust_executable_bit;
extern int quote_path_fully;
extern int has_symlinks;
extern int ignore_case;
extern int assume_unchanged;
extern int prefer_symlink_refs;
extern int log_all_ref_updates;
@@ -433,7 +441,15 @@ enum branch_track {
BRANCH_TRACK_EXPLICIT,
};
enum rebase_setup_type {
AUTOREBASE_NEVER = 0,
AUTOREBASE_LOCAL,
AUTOREBASE_REMOTE,
AUTOREBASE_ALWAYS,
};
extern enum branch_track git_branch_track;
extern enum rebase_setup_type autorebase;
#define GIT_REPO_VERSION 0
extern int repository_format_version;
@@ -592,7 +608,7 @@ struct checkout {
};
extern int checkout_entry(struct cache_entry *ce, const struct checkout *state, char *topath);
extern int has_symlink_leading_path(const char *name, char *last_symlink);
extern int has_symlink_leading_path(int len, const char *name);
extern struct alternate_object_database {
struct alternate_object_database *next;
@@ -636,6 +652,7 @@ struct ref {
struct ref *next;
unsigned char old_sha1[20];
unsigned char new_sha1[20];
char *symref;
unsigned int force:1,
merge:1,
nonfastforward:1,
@@ -720,6 +737,7 @@ extern int config_error_nonbool(const char *);
#define MAX_GITNAME (1000)
extern char git_default_email[MAX_GITNAME];
extern char git_default_name[MAX_GITNAME];
extern int user_ident_explicitly_given;
extern const char *git_commit_encoding;
extern const char *git_log_output_encoding;

View File

@@ -701,7 +701,7 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
else if (0 <= (fd = open(elem->path, O_RDONLY)) &&
!fstat(fd, &st)) {
size_t len = xsize_t(st.st_size);
size_t sz = 0;
ssize_t done;
int is_file, i;
elem->mode = canon_mode(st.st_mode);
@@ -716,14 +716,13 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
result_size = len;
result = xmalloc(len + 1);
while (sz < len) {
ssize_t done = xread(fd, result+sz, len-sz);
if (done == 0 && sz != len)
die("early EOF '%s'", elem->path);
else if (done < 0)
die("read error '%s'", elem->path);
sz += done;
}
done = read_in_full(fd, result, len);
if (done < 0)
die("read error '%s'", elem->path);
else if (done < len)
die("early EOF '%s'", elem->path);
result[len] = 0;
}
else {
@@ -798,7 +797,7 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
int deleted = 0;
if (rev->loginfo && !rev->no_commit_id)
show_log(rev, opt->msg_sep);
show_log(rev);
dump_quoted_path(dense ? "diff --cc " : "diff --combined ",
"", elem->path, c_meta, c_reset);
printf("%sindex ", c_meta);
@@ -881,7 +880,7 @@ static void show_raw_diff(struct combine_diff_path *p, int num_parent, struct re
inter_name_termination = 0;
if (rev->loginfo && !rev->no_commit_id)
show_log(rev, opt->msg_sep);
show_log(rev);
if (opt->output_format & DIFF_FORMAT_RAW) {
offset = strlen(COLONS) - num_parent;
@@ -962,7 +961,7 @@ void diff_tree_combined(const unsigned char *sha1,
paths = intersect_paths(paths, i, num_parent);
if (show_log_first && i == 0) {
show_log(rev, opt->msg_sep);
show_log(rev);
if (rev->verbose_header && opt->output_format)
putchar(opt->line_termination);
}

View File

@@ -1,5 +1,16 @@
/*
* The order of the following two lines is important.
*
* FREAD_READS_DIRECTORIES is undefined before including git-compat-util.h
* to avoid the redefinition of fopen within git-compat-util.h. This is
* necessary since fopen is a macro on some platforms which may be set
* based on compiler options. For example, on AIX fopen is set to fopen64
* when _LARGE_FILES is defined. The previous technique of merely undefining
* fopen after including git-compat-util.h is inadequate in this case.
*/
#undef FREAD_READS_DIRECTORIES
#include "../git-compat-util.h"
#undef fopen
FILE *git_fopen(const char *path, const char *mode)
{
FILE *fp;

View File

@@ -350,6 +350,11 @@ int git_default_config(const char *var, const char *value)
return 0;
}
if (!strcmp(var, "core.ignorecase")) {
ignore_case = git_config_bool(var, value);
return 0;
}
if (!strcmp(var, "core.bare")) {
is_bare_repository_cfg = git_config_bool(var, value);
return 0;
@@ -443,6 +448,8 @@ int git_default_config(const char *var, const char *value)
if (!value)
return config_error_nonbool(var);
strlcpy(git_default_name, value, sizeof(git_default_name));
if (git_default_email[0])
user_ident_explicitly_given = 1;
return 0;
}
@@ -450,6 +457,8 @@ int git_default_config(const char *var, const char *value)
if (!value)
return config_error_nonbool(var);
strlcpy(git_default_email, value, sizeof(git_default_email));
if (git_default_name[0])
user_ident_explicitly_given = 1;
return 0;
}
@@ -487,6 +496,21 @@ int git_default_config(const char *var, const char *value)
git_branch_track = git_config_bool(var, value);
return 0;
}
if (!strcmp(var, "branch.autosetuprebase")) {
if (!value)
return config_error_nonbool(var);
else if (!strcmp(value, "never"))
autorebase = AUTOREBASE_NEVER;
else if (!strcmp(value, "local"))
autorebase = AUTOREBASE_LOCAL;
else if (!strcmp(value, "remote"))
autorebase = AUTOREBASE_REMOTE;
else if (!strcmp(value, "always"))
autorebase = AUTOREBASE_ALWAYS;
else
return error("Malformed value for %s", var);
return 0;
}
/* Add other config variables here and to Documentation/config.txt. */
return 0;
@@ -607,11 +631,9 @@ static int store_aux(const char* key, const char* value)
case KEY_SEEN:
if (matches(key, value)) {
if (store.seen == 1 && store.multi_replace == 0) {
fprintf(stderr,
"Warning: %s has multiple values\n",
key);
warning("%s has multiple values", key);
} else if (store.seen >= MAX_MATCHES) {
fprintf(stderr, "Too many matches\n");
error("too many matches for %s", key);
return 1;
}
@@ -661,9 +683,9 @@ static int store_aux(const char* key, const char* value)
return 0;
}
static int write_error(void)
static int write_error(const char *filename)
{
fprintf(stderr, "Failed to write new configuration file\n");
error("failed to write new configuration file %s", filename);
/* Same error code as "failed to rename". */
return 4;
@@ -680,7 +702,7 @@ static int store_write_section(int fd, const char* key)
if (dot) {
strbuf_addf(&sb, "[%.*s \"", (int)(dot - key), key);
for (i = dot - key + 1; i < store.baselen; i++) {
if (key[i] == '"')
if (key[i] == '"' || key[i] == '\\')
strbuf_addch(&sb, '\\');
strbuf_addch(&sb, key[i]);
}
@@ -822,7 +844,7 @@ int git_config_set_multivar(const char* key, const char* value,
*/
if (last_dot == NULL) {
fprintf(stderr, "key does not contain a section: %s\n", key);
error("key does not contain a section: %s", key);
ret = 2;
goto out_free;
}
@@ -842,14 +864,14 @@ int git_config_set_multivar(const char* key, const char* value,
/* Leave the extended basename untouched.. */
if (!dot || i > store.baselen) {
if (!iskeychar(c) || (i == store.baselen+1 && !isalpha(c))) {
fprintf(stderr, "invalid key: %s\n", key);
error("invalid key: %s", key);
free(store.key);
ret = 1;
goto out_free;
}
c = tolower(c);
} else if (c == '\n') {
fprintf(stderr, "invalid key (newline): %s\n", key);
error("invalid key (newline): %s", key);
free(store.key);
ret = 1;
goto out_free;
@@ -865,7 +887,7 @@ int git_config_set_multivar(const char* key, const char* value,
lock = xcalloc(sizeof(struct lock_file), 1);
fd = hold_lock_file_for_update(lock, config_filename, 0);
if (fd < 0) {
fprintf(stderr, "could not lock config file\n");
error("could not lock config file %s", config_filename);
free(store.key);
ret = -1;
goto out_free;
@@ -912,8 +934,7 @@ int git_config_set_multivar(const char* key, const char* value,
store.value_regex = (regex_t*)xmalloc(sizeof(regex_t));
if (regcomp(store.value_regex, value_regex,
REG_EXTENDED)) {
fprintf(stderr, "Invalid pattern: %s\n",
value_regex);
error("invalid pattern: %s", value_regex);
free(store.value_regex);
ret = 6;
goto out_free;
@@ -931,7 +952,7 @@ int git_config_set_multivar(const char* key, const char* value,
* existing config file.
*/
if (git_config_from_file(store_aux, config_filename)) {
fprintf(stderr, "invalid config file\n");
error("invalid config file %s", config_filename);
free(store.key);
if (store.value_regex != NULL) {
regfree(store.value_regex);
@@ -1010,7 +1031,7 @@ int git_config_set_multivar(const char* key, const char* value,
}
if (commit_lock_file(lock) < 0) {
fprintf(stderr, "Cannot commit config file!\n");
error("could not commit config file %s", config_filename);
ret = 4;
goto out_free;
}
@@ -1031,7 +1052,7 @@ out_free:
return ret;
write_err_out:
ret = write_error();
ret = write_error(lock->filename);
goto out_free;
}
@@ -1081,7 +1102,7 @@ int git_config_rename_section(const char *old_name, const char *new_name)
config_filename = xstrdup(config_filename);
out_fd = hold_lock_file_for_update(lock, config_filename, 0);
if (out_fd < 0) {
ret = error("Could not lock config file!");
ret = error("could not lock config file %s", config_filename);
goto out;
}
@@ -1105,7 +1126,7 @@ int git_config_rename_section(const char *old_name, const char *new_name)
}
store.baselen = strlen(new_name);
if (!store_write_section(out_fd, new_name)) {
ret = write_error();
ret = write_error(lock->filename);
goto out;
}
continue;
@@ -1116,14 +1137,14 @@ int git_config_rename_section(const char *old_name, const char *new_name)
continue;
length = strlen(buf);
if (write_in_full(out_fd, buf, length) != length) {
ret = write_error();
ret = write_error(lock->filename);
goto out;
}
}
fclose(config_file);
unlock_and_out:
if (commit_lock_file(lock) < 0)
ret = error("Cannot commit config file!");
ret = error("could not commit config file %s", config_filename);
out:
free(config_filename);
return ret;

View File

@@ -780,7 +780,7 @@ _git_merge ()
;;
--*)
__gitcomp "
--no-commit --no-summary --squash --strategy
--no-commit --no-stat --log --no-log --squash --strategy
"
return
esac

View File

@@ -337,22 +337,41 @@ int run_diff_files_cmd(struct rev_info *revs, int argc, const char **argv)
}
return run_diff_files(revs, options);
}
/*
* See if work tree has an entity that can be staged. Return 0 if so,
* return 1 if not and return -1 if error.
* Has the work tree entity been removed?
*
* Return 1 if it was removed from the work tree, 0 if an entity to be
* compared with the cache entry ce still exists (the latter includes
* the case where a directory that is not a submodule repository
* exists for ce that is a submodule -- it is a submodule that is not
* checked out). Return negative for an error.
*/
static int check_work_tree_entity(const struct cache_entry *ce, struct stat *st, char *symcache)
static int check_removed(const struct cache_entry *ce, struct stat *st)
{
if (lstat(ce->name, st) < 0) {
if (errno != ENOENT && errno != ENOTDIR)
return -1;
return 1;
}
if (has_symlink_leading_path(ce->name, symcache))
if (has_symlink_leading_path(ce_namelen(ce), ce->name))
return 1;
if (S_ISDIR(st->st_mode)) {
unsigned char sub[20];
if (resolve_gitlink_ref(ce->name, "HEAD", sub))
/*
* If ce is already a gitlink, we can have a plain
* directory (i.e. the submodule is not checked out),
* or a checked out submodule. Either case this is not
* a case where something was removed from the work tree,
* so we will return 0.
*
* Otherwise, if the directory is not a submodule
* repository, that means ce which was a blob turned into
* a directory --- the blob was removed!
*/
if (!S_ISGITLINK(ce->ce_mode) &&
resolve_gitlink_ref(ce->name, "HEAD", sub))
return 1;
}
return 0;
@@ -402,7 +421,7 @@ int run_diff_files(struct rev_info *revs, unsigned int option)
memset(&(dpath->parent[0]), 0,
sizeof(struct combine_diff_parent)*5);
changed = check_work_tree_entity(ce, &st, symcache);
changed = check_removed(ce, &st);
if (!changed)
dpath->mode = ce_mode_from_stat(ce, st.st_mode);
else {
@@ -466,7 +485,7 @@ int run_diff_files(struct rev_info *revs, unsigned int option)
if (ce_uptodate(ce))
continue;
changed = check_work_tree_entity(ce, &st, symcache);
changed = check_removed(ce, &st);
if (changed) {
if (changed < 0) {
perror(ce->name);
@@ -479,8 +498,11 @@ int run_diff_files(struct rev_info *revs, unsigned int option)
continue;
}
changed = ce_match_stat(ce, &st, ce_option);
if (!changed && !DIFF_OPT_TST(&revs->diffopt, FIND_COPIES_HARDER))
continue;
if (!changed) {
ce_mark_uptodate(ce);
if (!DIFF_OPT_TST(&revs->diffopt, FIND_COPIES_HARDER))
continue;
}
oldmode = ce->ce_mode;
newmode = ce_mode_from_stat(ce, st.st_mode);
diff_change(&revs->diffopt, oldmode, newmode,
@@ -524,7 +546,7 @@ static int get_stat_data(struct cache_entry *ce,
if (!cached) {
int changed;
struct stat st;
changed = check_work_tree_entity(ce, &st, cbdata->symcache);
changed = check_removed(ce, &st);
if (changed < 0)
return -1;
else if (changed) {

3
diff.c
View File

@@ -19,7 +19,7 @@
#endif
static int diff_detect_rename_default;
static int diff_rename_limit_default = 100;
static int diff_rename_limit_default = 200;
int diff_use_color_default = -1;
static const char *external_diff_cmd_cfg;
int diff_auto_refresh_index = 1;
@@ -2220,7 +2220,6 @@ void diff_setup(struct diff_options *options)
options->rename_limit = -1;
options->dirstat_percent = 3;
options->context = 3;
options->msg_sep = "";
options->change = diff_change;
options->add_remove = diff_addremove;

2
diff.h
View File

@@ -83,12 +83,12 @@ struct diff_options {
int pickaxe_opts;
int rename_score;
int rename_limit;
int warn_on_too_large_rename;
int dirstat_percent;
int setup;
int abbrev;
const char *prefix;
int prefix_length;
const char *msg_sep;
const char *stat_sep;
long xdl_opts;

View File

@@ -492,7 +492,8 @@ void diffcore_rename(struct diff_options *options)
rename_limit = 32767;
if ((num_create > rename_limit && num_src > rename_limit) ||
(num_create * num_src > rename_limit * rename_limit)) {
warning("too many files, skipping inexact rename detection");
if (options->warn_on_too_large_rename)
warning("too many files, skipping inexact rename detection");
goto cleanup;
}

24
dir.c
View File

@@ -52,6 +52,11 @@ int common_prefix(const char **pathspec)
return prefix;
}
static inline int special_char(unsigned char c1)
{
return !c1 || c1 == '*' || c1 == '[' || c1 == '?';
}
/*
* Does 'match' matches the given name?
* A match is found if
@@ -69,14 +74,27 @@ static int match_one(const char *match, const char *name, int namelen)
int matchlen;
/* If the match was just the prefix, we matched */
matchlen = strlen(match);
if (!matchlen)
if (!*match)
return MATCHED_RECURSIVELY;
for (;;) {
unsigned char c1 = *match;
unsigned char c2 = *name;
if (special_char(c1))
break;
if (c1 != c2)
return 0;
match++;
name++;
namelen--;
}
/*
* If we don't match the matchstring exactly,
* we need to match by fnmatch
*/
matchlen = strlen(match);
if (strncmp(match, name, matchlen))
return !fnmatch(match, name, 0) ? MATCHED_FNMATCH : 0;
@@ -371,7 +389,7 @@ static struct dir_entry *dir_entry_new(const char *pathname, int len)
struct dir_entry *dir_add_name(struct dir_struct *dir, const char *pathname, int len)
{
if (cache_name_exists(pathname, len))
if (cache_name_exists(pathname, len, ignore_case))
return NULL;
ALLOC_GROW(dir->entries, dir->nr+1, dir->alloc);

View File

@@ -11,9 +11,11 @@
char git_default_email[MAX_GITNAME];
char git_default_name[MAX_GITNAME];
int user_ident_explicitly_given;
int trust_executable_bit = 1;
int quote_path_fully = 1;
int has_symlinks = 1;
int ignore_case;
int assume_unchanged;
int prefer_symlink_refs;
int is_bare_repository_cfg = -1; /* unspecified */
@@ -38,6 +40,7 @@ int auto_crlf = 0; /* 1: both ways, -1: only when adding git objects */
enum safe_crlf safe_crlf = SAFE_CRLF_WARN;
unsigned whitespace_rule_cfg = WS_DEFAULT_RULE;
enum branch_track git_branch_track = BRANCH_TRACK_REMOTE;
enum rebase_setup_type autorebase = AUTOREBASE_NEVER;
/* This is set by setup_git_dir_gently() and/or git_default_config() */
char *git_work_tree_cfg;
@@ -49,6 +52,8 @@ static char *git_object_dir, *git_index_file, *git_refs_dir, *git_graft_file;
static void setup_git_env(void)
{
git_dir = getenv(GIT_DIR_ENVIRONMENT);
if (!git_dir)
git_dir = read_gitfile_gently(DEFAULT_GIT_DIR_ENVIRONMENT);
if (!git_dir)
git_dir = DEFAULT_GIT_DIR_ENVIRONMENT;
git_object_dir = getenv(DB_ENVIRONMENT);

View File

@@ -1692,7 +1692,7 @@ static void skip_optional_lf(void)
ungetc(term_char, stdin);
}
static void cmd_mark(void)
static void parse_mark(void)
{
if (!prefixcmp(command_buf.buf, "mark :")) {
next_mark = strtoumax(command_buf.buf + 6, NULL, 10);
@@ -1702,7 +1702,7 @@ static void cmd_mark(void)
next_mark = 0;
}
static void cmd_data(struct strbuf *sb)
static void parse_data(struct strbuf *sb)
{
strbuf_reset(sb);
@@ -1800,13 +1800,13 @@ static char *parse_ident(const char *buf)
return ident;
}
static void cmd_new_blob(void)
static void parse_new_blob(void)
{
static struct strbuf buf = STRBUF_INIT;
read_next_command();
cmd_mark();
cmd_data(&buf);
parse_mark();
parse_data(&buf);
store_object(OBJ_BLOB, &buf, &last_blob, NULL, next_mark);
}
@@ -1910,7 +1910,7 @@ static void file_change_m(struct branch *b)
p = uq.buf;
}
read_next_command();
cmd_data(&buf);
parse_data(&buf);
store_object(OBJ_BLOB, &buf, &last_blob, sha1, 0);
} else if (oe) {
if (oe->type != OBJ_BLOB)
@@ -1997,7 +1997,7 @@ static void file_change_deleteall(struct branch *b)
load_tree(&b->branch_tree);
}
static void cmd_from_commit(struct branch *b, char *buf, unsigned long size)
static void parse_from_commit(struct branch *b, char *buf, unsigned long size)
{
if (!buf || size < 46)
die("Not a valid commit: %s", sha1_to_hex(b->sha1));
@@ -2008,7 +2008,7 @@ static void cmd_from_commit(struct branch *b, char *buf, unsigned long size)
b->branch_tree.versions[1].sha1);
}
static void cmd_from_existing(struct branch *b)
static void parse_from_existing(struct branch *b)
{
if (is_null_sha1(b->sha1)) {
hashclr(b->branch_tree.versions[0].sha1);
@@ -2019,12 +2019,12 @@ static void cmd_from_existing(struct branch *b)
buf = read_object_with_reference(b->sha1,
commit_type, &size, b->sha1);
cmd_from_commit(b, buf, size);
parse_from_commit(b, buf, size);
free(buf);
}
}
static int cmd_from(struct branch *b)
static int parse_from(struct branch *b)
{
const char *from;
struct branch *s;
@@ -2055,12 +2055,12 @@ static int cmd_from(struct branch *b)
if (oe->pack_id != MAX_PACK_ID) {
unsigned long size;
char *buf = gfi_unpack_entry(oe, &size);
cmd_from_commit(b, buf, size);
parse_from_commit(b, buf, size);
free(buf);
} else
cmd_from_existing(b);
parse_from_existing(b);
} else if (!get_sha1(from, b->sha1))
cmd_from_existing(b);
parse_from_existing(b);
else
die("Invalid ref name or SHA1 expression: %s", from);
@@ -2068,7 +2068,7 @@ static int cmd_from(struct branch *b)
return 1;
}
static struct hash_list *cmd_merge(unsigned int *count)
static struct hash_list *parse_merge(unsigned int *count)
{
struct hash_list *list = NULL, *n, *e = e;
const char *from;
@@ -2109,7 +2109,7 @@ static struct hash_list *cmd_merge(unsigned int *count)
return list;
}
static void cmd_new_commit(void)
static void parse_new_commit(void)
{
static struct strbuf msg = STRBUF_INIT;
struct branch *b;
@@ -2126,7 +2126,7 @@ static void cmd_new_commit(void)
b = new_branch(sp);
read_next_command();
cmd_mark();
parse_mark();
if (!prefixcmp(command_buf.buf, "author ")) {
author = parse_ident(command_buf.buf + 7);
read_next_command();
@@ -2137,10 +2137,10 @@ static void cmd_new_commit(void)
}
if (!committer)
die("Expected committer but didn't get one");
cmd_data(&msg);
parse_data(&msg);
read_next_command();
cmd_from(b);
merge_list = cmd_merge(&merge_count);
parse_from(b);
merge_list = parse_merge(&merge_count);
/* ensure the branch is active/loaded */
if (!b->branch_tree.tree || !max_active_branches) {
@@ -2198,7 +2198,7 @@ static void cmd_new_commit(void)
b->last_commit = object_count_by_type[OBJ_COMMIT];
}
static void cmd_new_tag(void)
static void parse_new_tag(void)
{
static struct strbuf msg = STRBUF_INIT;
char *sp;
@@ -2255,7 +2255,7 @@ static void cmd_new_tag(void)
/* tag payload/message */
read_next_command();
cmd_data(&msg);
parse_data(&msg);
/* build the tag object */
strbuf_reset(&new_data);
@@ -2275,7 +2275,7 @@ static void cmd_new_tag(void)
t->pack_id = pack_id;
}
static void cmd_reset_branch(void)
static void parse_reset_branch(void)
{
struct branch *b;
char *sp;
@@ -2295,12 +2295,12 @@ static void cmd_reset_branch(void)
else
b = new_branch(sp);
read_next_command();
cmd_from(b);
parse_from(b);
if (command_buf.len > 0)
unread_command_buf = 1;
}
static void cmd_checkpoint(void)
static void parse_checkpoint(void)
{
if (object_count) {
cycle_packfile();
@@ -2311,7 +2311,7 @@ static void cmd_checkpoint(void)
skip_optional_lf();
}
static void cmd_progress(void)
static void parse_progress(void)
{
fwrite(command_buf.buf, 1, command_buf.len, stdout);
fputc('\n', stdout);
@@ -2451,17 +2451,17 @@ int main(int argc, const char **argv)
set_die_routine(die_nicely);
while (read_next_command() != EOF) {
if (!strcmp("blob", command_buf.buf))
cmd_new_blob();
parse_new_blob();
else if (!prefixcmp(command_buf.buf, "commit "))
cmd_new_commit();
parse_new_commit();
else if (!prefixcmp(command_buf.buf, "tag "))
cmd_new_tag();
parse_new_tag();
else if (!prefixcmp(command_buf.buf, "reset "))
cmd_reset_branch();
parse_reset_branch();
else if (!strcmp("checkpoint", command_buf.buf))
cmd_checkpoint();
parse_checkpoint();
else if (!prefixcmp(command_buf.buf, "progress "))
cmd_progress();
parse_progress();
else
die("Unsupported command: %s", command_buf.buf);
}

View File

@@ -69,14 +69,19 @@ bisect_start() {
head=$(GIT_DIR="$GIT_DIR" git symbolic-ref -q HEAD) ||
head=$(GIT_DIR="$GIT_DIR" git rev-parse --verify HEAD) ||
die "Bad HEAD - I need a HEAD"
#
# Check that we either already have BISECT_START, or that the
# branches bisect, new-bisect don't exist, to not override them.
#
test -s "$GIT_DIR/BISECT_START" ||
if git show-ref --verify -q refs/heads/bisect ||
git show-ref --verify -q refs/heads/new-bisect; then
die 'The branches "bisect" and "new-bisect" must not exist.'
fi
start_head=''
case "$head" in
refs/heads/bisect)
if [ -s "$GIT_DIR/BISECT_START" ]; then
branch=`cat "$GIT_DIR/BISECT_START"`
else
branch=master
fi
branch=`cat "$GIT_DIR/BISECT_START"`
git checkout $branch || exit
;;
refs/heads/*|$_x40)
@@ -219,18 +224,33 @@ bisect_auto_next() {
bisect_next_check && bisect_next || :
}
eval_rev_list() {
_eval="$1"
eval $_eval
res=$?
if [ $res -ne 0 ]; then
echo >&2 "'git rev-list --bisect-vars' failed:"
echo >&2 "maybe you mistake good and bad revs?"
exit $res
fi
return $res
}
filter_skipped() {
_eval="$1"
_skip="$2"
if [ -z "$_skip" ]; then
eval $_eval
eval_rev_list "$_eval"
return
fi
# Let's parse the output of:
# "git rev-list --bisect-vars --bisect-all ..."
eval $_eval | while read hash line
eval_rev_list "$_eval" | while read hash line
do
case "$VARS,$FOUND,$TRIED,$hash" in
# We display some vars.
@@ -328,8 +348,8 @@ bisect_next() {
exit_if_skipped_commits "$bisect_rev"
echo "Bisecting: $bisect_nr revisions left to test after this"
git branch -f new-bisect "$bisect_rev"
git checkout -q new-bisect || exit
git branch -D new-bisect 2> /dev/null
git checkout -q -b new-bisect "$bisect_rev" || exit
git branch -M new-bisect bisect
git show-branch "$bisect_rev"
}

View File

@@ -290,7 +290,6 @@ die "working tree '$GIT_WORK_TREE' already exists."
D=
W=
cleanup() {
err=$?
test -z "$D" && rm -rf "$dir"
test -z "$W" && test -n "$GIT_WORK_TREE" && rm -rf "$GIT_WORK_TREE"
cd ..
@@ -298,7 +297,7 @@ cleanup() {
test -n "$W" && rm -rf "$W"
exit $err
}
trap cleanup 0
trap 'err=$?; cleanup' 0
mkdir -p "$dir" && D=$(cd "$dir" && pwd) || usage
test -n "$GIT_WORK_TREE" && mkdir -p "$GIT_WORK_TREE" &&
W=$(cd "$GIT_WORK_TREE" && pwd) && GIT_WORK_TREE="$W" && export GIT_WORK_TREE
@@ -384,7 +383,10 @@ yes)
fi
fi &&
cd "$repo" &&
find objects -depth -print | cpio $cpio_quiet_flag -pumd$l "$GIT_DIR/" || \
# Create dirs using umask and permissions and destination
find objects -type d -print | (cd "$GIT_DIR" && xargs mkdir -p) &&
# Copy existing 0444 permissions on content
find objects ! -type d -print | cpio $cpio_quiet_flag -pumd$l "$GIT_DIR/" || \
exit 1
fi
git-ls-remote "$repo" >"$GIT_DIR/CLONE_HEAD" || exit 1

View File

@@ -229,6 +229,9 @@ void *gitmemmem(const void *haystack, size_t haystacklen,
#endif
#ifdef FREAD_READS_DIRECTORIES
#ifdef fopen
#undef fopen
#endif
#define fopen(a,b) git_fopen(a,b)
extern FILE *git_fopen(const char*, const char*);
#endif

View File

@@ -406,8 +406,22 @@ if [ "$filter_tag_name" ]; then
echo "$ref -> $new_ref ($sha1 -> $new_sha1)"
if [ "$type" = "tag" ]; then
# Warn that we are not rewriting the tag object itself.
warn "unreferencing tag object $sha1t"
new_sha1=$(git cat-file tag "$ref" |
sed -n \
-e "1,/^$/{
s/^object .*/object $new_sha1/
s/^type .*/type commit/
s/^tag .*/tag $new_ref/
}" \
-e '/^-----BEGIN PGP SIGNATURE-----/q' \
-e 'p' |
git mktag) ||
die "Could not create new tag object for $ref"
if git cat-file tag "$ref" | \
grep '^-----BEGIN PGP SIGNATURE-----' >/dev/null 2>&1
then
warn "gpg signature stripped from tag object $sha1t"
fi
fi
git update-ref "refs/tags/$new_ref" "$new_sha1" ||
@@ -421,11 +435,17 @@ rm -rf "$tempdir"
trap - 0
unset GIT_DIR GIT_WORK_TREE GIT_INDEX_FILE
test -z "$ORIG_GIT_DIR" || GIT_DIR="$ORIG_GIT_DIR" && export GIT_DIR
test -z "$ORIG_GIT_WORK_TREE" || GIT_WORK_TREE="$ORIG_GIT_WORK_TREE" &&
test -z "$ORIG_GIT_DIR" || {
GIT_DIR="$ORIG_GIT_DIR" && export GIT_DIR
}
test -z "$ORIG_GIT_WORK_TREE" || {
GIT_WORK_TREE="$ORIG_GIT_WORK_TREE" &&
export GIT_WORK_TREE
test -z "$ORIG_GIT_INDEX_FILE" || GIT_INDEX_FILE="$ORIG_GIT_INDEX_FILE" &&
}
test -z "$ORIG_GIT_INDEX_FILE" || {
GIT_INDEX_FILE="$ORIG_GIT_INDEX_FILE" &&
export GIT_INDEX_FILE
}
git read-tree -u -m HEAD
exit $ret

View File

@@ -601,6 +601,7 @@ proc apply_config {} {
}
}
set default_config(branch.autosetupmerge) true
set default_config(merge.diffstat) true
set default_config(merge.summary) false
set default_config(merge.verbosity) 2

View File

@@ -183,6 +183,9 @@ method _create {} {
if {$spec ne {} && $opt_fetch} {
$co enable_fetch $spec
}
if {$spec ne {}} {
$co remote_source $spec
}
if {[$co run]} {
destroy $w

View File

@@ -127,7 +127,7 @@ method _delete {} {
foreach i $to_delete {
set b [lindex $i 0]
set o [lindex $i 1]
if {[catch {git update-ref -d "refs/heads/$b" $o} err]} {
if {[catch {git branch -D $b} err]} {
append failed " - $b: $err\n"
}
}

View File

@@ -16,6 +16,7 @@ field merge_base {}; # merge base if we have another ref involved
field fetch_spec {}; # refetch tracking branch if used?
field checkout 1; # actually checkout the branch?
field create 0; # create the branch if it doesn't exist?
field remote_source {}; # same as fetch_spec, to setup tracking
field reset_ok 0; # did the user agree to reset?
field fetch_ok 0; # did the fetch succeed?
@@ -44,6 +45,10 @@ method enable_fetch {spec} {
set fetch_spec $spec
}
method remote_source {spec} {
set remote_source $spec
}
method enable_checkout {co} {
set checkout $co
}
@@ -145,7 +150,7 @@ method _finish_fetch {ok} {
}
method _update_ref {} {
global null_sha1 current_branch
global null_sha1 current_branch repo_config
set ref $new_ref
set new $new_hash
@@ -172,6 +177,23 @@ method _update_ref {} {
set reflog_msg "branch: Created from $new_expr"
set cur $null_sha1
if {($repo_config(branch.autosetupmerge) eq {true}
|| $repo_config(branch.autosetupmerge) eq {always})
&& $remote_source ne {}
&& "refs/heads/$newbranch" eq $ref} {
set c_remote [lindex $remote_source 1]
set c_merge [lindex $remote_source 2]
if {[catch {
git config branch.$newbranch.remote $c_remote
git config branch.$newbranch.merge $c_merge
} err]} {
_error $this [strcat \
[mc "Failed to configure simplified git-pull for '%s'." $newbranch] \
"\n\n$err"]
}
}
} elseif {$create && $merge_type eq {none}} {
# We were told to create it, but not do a merge.
# Bad. Name shouldn't have existed.

View File

@@ -102,8 +102,8 @@ proc hint_gc {} {
*]]
if {$objects_current >= $object_limit} {
set objects_current [expr {$objects_current * 256}]
set object_limit [expr {$object_limit * 256}]
set objects_current [expr {$objects_current * 250}]
set object_limit [expr {$object_limit * 250}]
if {[ask_popup \
[mc "This repository currently has approximately %i loose objects.

View File

@@ -84,13 +84,19 @@ method _connect {pipe_fd} {
regexp \
{International Ispell Version .* \(but really (Aspell .*?)\)$} \
$s_version _junk s_version
regexp {^Aspell (\d)+\.(\d+)} $s_version _junk major minor
puts $pipe_fd ! ; # enable terse mode
puts $pipe_fd {$$cr master} ; # fetch the language
flush $pipe_fd
gets $pipe_fd s_lang
regexp {[/\\]([^/\\]+)\.[^\.]+$} $s_lang _ s_lang
# fetch the language
if {$major > 0 || ($major == 0 && $minor >= 60)} {
puts $pipe_fd {$$cr master}
flush $pipe_fd
gets $pipe_fd s_lang
regexp {[/\\]([^/\\]+)\.[^\.]+$} $s_lang _ s_lang
} else {
set s_lang {}
}
if {$::default_config(gui.spellingdictionary) eq {}
&& [get_config gui.spellingdictionary] eq {}} {

View File

@@ -8,7 +8,7 @@ msgstr ""
"Project-Id-Version: git-gui\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2008-03-14 07:18+0100\n"
"PO-Revision-Date: 2008-02-16 21:52+0100\n"
"PO-Revision-Date: 2008-05-01 11:51+0200\n"
"Last-Translator: Christian Stimming <stimming@tuhh.de>\n"
"Language-Team: German\n"
"MIME-Version: 1.0\n"
@@ -1754,9 +1754,8 @@ msgid "Number of Diff Context Lines"
msgstr "Anzahl der Kontextzeilen beim Vergleich"
#: lib/option.tcl:127
#, fuzzy
msgid "Commit Message Text Width"
msgstr "Versionsbeschreibung:"
msgstr "Textbreite der Versionsbeschreibung"
#: lib/option.tcl:128
msgid "New Branch Name Template"
@@ -1895,40 +1894,36 @@ msgstr "Fehler beim Erstellen des Icons:"
#: lib/spellcheck.tcl:57
msgid "Unsupported spell checker"
msgstr ""
msgstr "Rechtschreibprüfungsprogramm nicht unterstützt"
#: lib/spellcheck.tcl:65
#, fuzzy
msgid "Spell checking is unavailable"
msgstr "Rechtschreibprüfung fehlgeschlagen"
msgstr "Rechtschreibprüfung nicht verfügbar"
#: lib/spellcheck.tcl:68
msgid "Invalid spell checking configuration"
msgstr ""
msgstr "Unbenutzbare Konfiguration der Rechtschreibprüfung"
#: lib/spellcheck.tcl:70
#, tcl-format
msgid "Reverting dictionary to %s."
msgstr ""
msgstr "Wörterbuch auf %s zurückgesetzt."
#: lib/spellcheck.tcl:73
#, fuzzy
msgid "Spell checker silently failed on startup"
msgstr "Rechtschreibprüfung fehlgeschlagen"
msgstr "Rechtschreibprüfungsprogramm mit Fehler abgebrochen"
#: lib/spellcheck.tcl:80
#, fuzzy
msgid "Unrecognized spell checker"
msgstr "Unbekannte Version von »aspell«"
msgstr "Unbekanntes Rechtschreibprüfungsprogramm"
#: lib/spellcheck.tcl:180
msgid "No Suggestions"
msgstr "Keine Vorschläge"
#: lib/spellcheck.tcl:381
#, fuzzy
msgid "Unexpected EOF from spell checker"
msgstr "Unerwartetes EOF von »aspell«"
msgstr "Unerwartetes EOF vom Rechtschreibprüfungsprogramm"
#: lib/spellcheck.tcl:385
msgid "Spell Checker Failed"
@@ -2002,6 +1997,3 @@ msgstr "Kompaktes Datenformat benutzen (für langsame Netzverbindungen)"
#: lib/transport.tcl:168
msgid "Include tags"
msgstr "Mit Markierungen übertragen"
#~ msgid "Not connected to aspell"
#~ msgstr "Keine Verbindung zu »aspell«"

View File

@@ -8,8 +8,12 @@ OPTIONS_SPEC="\
git-merge [options] <remote>...
git-merge [options] <msg> HEAD <remote>
--
summary show a diffstat at the end of the merge
n,no-summary don't show a diffstat at the end of the merge
stat show a diffstat at the end of the merge
n,no-stat don't show a diffstat at the end of the merge
summary (synonym to --stat)
no-summary (synonym to --no-stat)
log add list of one-line log to merge commit message
no-log don't add list of one-line log to merge commit message
squash create a single commit instead of doing a merge
commit perform a commit if the merge sucesses (default)
ff allow fast forward (default)
@@ -37,7 +41,7 @@ use_strategies=
allow_fast_forward=t
allow_trivial_merge=t
squash= no_commit=
squash= no_commit= log_arg=
dropsave() {
rm -f -- "$GIT_DIR/MERGE_HEAD" "$GIT_DIR/MERGE_MSG" \
@@ -148,10 +152,12 @@ merge_name () {
parse_config () {
while test $# != 0; do
case "$1" in
-n|--no-summary)
-n|--no-stat|--no-summary)
show_diffstat=false ;;
--summary)
--stat|--summary)
show_diffstat=t ;;
--log|--no-log)
log_arg=$1 ;;
--squash)
test "$allow_fast_forward" = t ||
die "You cannot combine --squash with --no-ff."
@@ -210,6 +216,7 @@ while test $args_left -lt $#; do shift; done
if test -z "$show_diffstat"; then
test "$(git config --bool merge.diffstat)" = false && show_diffstat=false
test "$(git config --bool merge.stat)" = false && show_diffstat=false
test -z "$show_diffstat" && show_diffstat=t
fi
@@ -258,7 +265,7 @@ else
merge_name=$(for remote
do
merge_name "$remote"
done | git fmt-merge-msg
done | git fmt-merge-msg $log_arg
)
merge_msg="${merge_msg:+$merge_msg$LF$LF}$merge_name"
fi

View File

@@ -237,9 +237,9 @@ merge_file () {
ecmerge)
touch "$BACKUP"
if base_present; then
"$merge_tool_path" "$BASE" "$LOCAL" "$REMOTE" --mode=merge3 --to="$MERGED"
"$merge_tool_path" "$BASE" "$LOCAL" "$REMOTE" --default --mode=merge3 --to="$MERGED"
else
"$merge_tool_path" "$LOCAL" "$REMOTE" --mode=merge2 --to="$MERGED"
"$merge_tool_path" "$LOCAL" "$REMOTE" --default --mode=merge2 --to="$MERGED"
fi
check_unchanged
;;

View File

@@ -4,7 +4,7 @@
#
# Fetch one or more remote refs and merge it/them into the current HEAD.
USAGE='[-n | --no-summary] [--[no-]commit] [--[no-]squash] [--[no-]ff] [-s strategy]... [<fetch-options>] <repo> <head>...'
USAGE='[-n | --no-stat] [--[no-]commit] [--[no-]squash] [--[no-]ff] [-s strategy]... [<fetch-options>] <repo> <head>...'
LONG_USAGE='Fetch one or more remote refs and merge it/them into the current HEAD.'
SUBDIRECTORY_OK=Yes
OPTIONS_SPEC=
@@ -16,19 +16,19 @@ cd_to_toplevel
test -z "$(git ls-files -u)" ||
die "You are in the middle of a conflicted merge."
strategy_args= no_summary= no_commit= squash= no_ff=
strategy_args= no_stat= no_commit= squash= no_ff= log_arg=
curr_branch=$(git symbolic-ref -q HEAD)
curr_branch_short=$(echo "$curr_branch" | sed "s|refs/heads/||")
rebase=$(git config --bool branch.$curr_branch_short.rebase)
while :
do
case "$1" in
-n|--n|--no|--no-|--no-s|--no-su|--no-sum|--no-summ|\
--no-summa|--no-summar|--no-summary)
no_summary=-n ;;
--summary)
no_summary=$1
;;
-n|--no-stat|--no-summary)
no_stat=-n ;;
--stat|--summary)
no_stat=$1 ;;
--log|--no-log)
log_arg=$1 ;;
--no-c|--no-co|--no-com|--no-comm|--no-commi|--no-commit)
no_commit=--no-commit ;;
--c|--co|--com|--comm|--commi|--commit)
@@ -172,9 +172,9 @@ then
exit
fi
merge_name=$(git fmt-merge-msg <"$GIT_DIR/FETCH_HEAD") || exit
merge_name=$(git fmt-merge-msg $log_arg <"$GIT_DIR/FETCH_HEAD") || exit
test true = "$rebase" &&
exec git-rebase $strategy_args --onto $merge_head \
${oldremoteref:-$merge_head}
exec git-merge $no_summary $no_commit $squash $no_ff $strategy_args \
exec git-merge $no_stat $no_commit $squash $no_ff $log_arg $strategy_args \
"$merge_name" HEAD $merge_head

View File

@@ -214,7 +214,7 @@ do
else
die "No rebase in progress?"
fi
git reset --hard $(cat $dotest/orig-head)
git reset --hard $(cat "$dotest/orig-head")
rm -r "$dotest"
exit
;;
@@ -353,7 +353,7 @@ orig_head=$branch
mb=$(git merge-base "$onto" "$branch")
if test "$upstream" = "$onto" && test "$mb" = "$onto" &&
# linear history?
! git rev-list --parents "$onto".."$branch" | grep " .* " > /dev/null
! (git rev-list --parents "$onto".."$branch" | grep " .* ") > /dev/null
then
# Lazily switch to the target branch if needed...
test -z "$switch_to" || git checkout "$switch_to"

View File

@@ -11,6 +11,7 @@ a pack everything in a single pack
A same as -a, and keep unreachable objects too
d remove redundant packs, and run git-prune-packed
f pass --no-reuse-delta to git-pack-objects
n do not run git-update-server-info
q,quiet be quiet
l pass --local to git-pack-objects
Packing constraints

View File

@@ -203,6 +203,7 @@ my %config_settings = (
"smtpuser" => \$smtp_authuser,
"smtppass" => \$smtp_authpass,
"to" => \@to,
"cc" => \@initial_cc,
"cccmd" => \$cc_cmd,
"aliasfiletype" => \$aliasfiletype,
"bcc" => \@bcclist,
@@ -512,7 +513,7 @@ EOT
close(C);
my $editor = $ENV{GIT_EDITOR} || Git::config(@repo, "core.editor") || $ENV{VISUAL} || $ENV{EDITOR} || "vi";
system('sh', '-c', '$0 $@', $editor, $compose_filename);
system('sh', '-c', $editor.' "$@"', $editor, $compose_filename);
open(C2,">",$compose_filename . ".final")
or die "Failed to open $compose_filename.final : " . $!;

View File

@@ -5,7 +5,7 @@
# Copyright (c) 2007 Lars Hjemli
USAGE="[--quiet] [--cached] \
[add <repo> [-b branch]|status|init|update|summary [-n|--summary-limit <n>] [<commit>]] \
[add <repo> [-b branch]|status|init|update [-i|--init]|summary [-n|--summary-limit <n>] [<commit>]] \
[--] [<path>...]"
OPTIONS_SPEC=
. git-sh-setup
@@ -74,8 +74,7 @@ module_name()
{
# Do we have "submodule.<something>.path = $1" defined in .gitmodules file?
re=$(printf '%s' "$1" | sed -e 's/[].[^$\\*]/\\&/g')
name=$( GIT_CONFIG=.gitmodules \
git config --get-regexp '^submodule\..*\.path$' |
name=$( git config -f .gitmodules --get-regexp '^submodule\..*\.path$' |
sed -n -e 's|^submodule\.\(.*\)\.path '"$re"'$|\1|p' )
test -z "$name" &&
die "No submodule mapping found in .gitmodules for path '$path'"
@@ -198,8 +197,8 @@ cmd_add()
git add "$path" ||
die "Failed to add submodule '$path'"
GIT_CONFIG=.gitmodules git config submodule."$path".path "$path" &&
GIT_CONFIG=.gitmodules git config submodule."$path".url "$repo" &&
git config -f .gitmodules submodule."$path".path "$path" &&
git config -f .gitmodules submodule."$path".url "$repo" &&
git add .gitmodules ||
die "Failed to register submodule '$path'"
}
@@ -240,7 +239,7 @@ cmd_init()
url=$(git config submodule."$name".url)
test -z "$url" || continue
url=$(GIT_CONFIG=.gitmodules git config submodule."$name".url)
url=$(git config -f .gitmodules submodule."$name".url)
test -z "$url" &&
die "No url found for submodule path '$path' in .gitmodules"
@@ -272,6 +271,10 @@ cmd_update()
-q|--quiet)
quiet=1
;;
-i|--init)
shift
cmd_init "$@" || return
;;
--)
shift
break
@@ -297,10 +300,11 @@ cmd_update()
# path have been specified
test "$#" != "0" &&
say "Submodule path '$path' not initialized"
say "Maybe you want to use 'update --init'?"
continue
fi
if ! test -d "$path"/.git
if ! test -d "$path"/.git -o -f "$path"/.git
then
module_clone "$path" "$url" || exit
subsha1=
@@ -555,7 +559,7 @@ cmd_status()
do
name=$(module_name "$path") || exit
url=$(git config submodule."$name".url)
if test -z "$url" || ! test -d "$path"/.git
if test -z "$url" || ! test -d "$path"/.git -o -f "$path"/.git
then
say "-$sha1 $path"
continue;

View File

@@ -65,7 +65,8 @@ my ($_stdin, $_help, $_edit,
$_template, $_shared,
$_version, $_fetch_all, $_no_rebase,
$_merge, $_strategy, $_dry_run, $_local,
$_prefix, $_no_checkout, $_url, $_verbose);
$_prefix, $_no_checkout, $_url, $_verbose,
$_git_format);
$Git::SVN::_follow_parent = 1;
my %remote_opts = ( 'username=s' => \$Git::SVN::Prompt::_username,
'config-dir=s' => \$Git::SVN::Ra::config_dir,
@@ -188,7 +189,7 @@ my %cmd = (
{ 'url' => \$_url, } ],
'blame' => [ \&Git::SVN::Log::cmd_blame,
"Show what revision and author last modified each line of a file",
{} ],
{ 'git-format' => \$_git_format } ],
);
my $cmd;
@@ -225,7 +226,7 @@ unless ($cmd && $cmd =~ /(?:clone|init|multi-init)$/) {
my %opts = %{$cmd{$cmd}->[2]} if (defined $cmd);
read_repo_config(\%opts);
Getopt::Long::Configure('pass_through') if ($cmd && $cmd eq 'log');
Getopt::Long::Configure('pass_through') if ($cmd && ($cmd eq 'log' || $cmd eq 'blame'));
my $rv = GetOptions(%opts, 'help|H|h' => \$_help, 'version|V' => \$_version,
'minimize-connections' => \$Git::SVN::Migration::_minimize,
'id|i=s' => \$Git::SVN::default_ref_id,
@@ -614,7 +615,7 @@ sub cmd_create_ignore {
print GITIGNORE "$s\n";
close(GITIGNORE)
or fatal("Failed to close `$ignore': $!");
command_noisy('add', $ignore);
command_noisy('add', '-f', $ignore);
});
}
@@ -2428,13 +2429,15 @@ sub make_log_entry {
$name_field = $1;
}
if (!defined $name_field) {
#
if (!defined $email) {
$email = $name;
}
} elsif ($name_field =~ /(.*?)\s+<(.*)>/) {
($name, $email) = ($1, $2);
} elsif ($name_field =~ /(.*)@/) {
($name, $email) = ($1, $name_field);
} else {
($name, $email) = ($name_field, 'unknown');
($name, $email) = ($name_field, $name_field);
}
}
if (defined $headrev && $self->use_svm_props) {
@@ -3671,7 +3674,7 @@ sub escape_uri_only {
my ($uri) = @_;
my @tmp;
foreach (split m{/}, $uri) {
s/([^\w.%-]|%(?![a-fA-F0-9]{2}))/sprintf("%%%02X",ord($1))/eg;
s/([^\w.%+-]|%(?![a-fA-F0-9]{2}))/sprintf("%%%02X",ord($1))/eg;
push @tmp, $_;
}
join('/', @tmp);
@@ -4466,19 +4469,51 @@ out:
}
sub cmd_blame {
my $path = shift;
my $path = pop;
config_pager();
run_pager();
my ($fh, $ctx) = command_output_pipe('blame', @_, $path);
while (my $line = <$fh>) {
if ($line =~ /^\^?([[:xdigit:]]+)\s/) {
my (undef, $rev, undef) = ::cmt_metadata($1);
$rev = sprintf('%-10s', $rev);
$line =~ s/^\^?[[:xdigit:]]+(\s)/$rev$1/;
my ($fh, $ctx, $rev);
if ($_git_format) {
($fh, $ctx) = command_output_pipe('blame', @_, $path);
while (my $line = <$fh>) {
if ($line =~ /^\^?([[:xdigit:]]+)\s/) {
# Uncommitted edits show up as a rev ID of
# all zeros, which we can't look up with
# cmt_metadata
if ($1 !~ /^0+$/) {
(undef, $rev, undef) =
::cmt_metadata($1);
$rev = '0' if (!$rev);
} else {
$rev = '0';
}
$rev = sprintf('%-10s', $rev);
$line =~ s/^\^?[[:xdigit:]]+(\s)/$rev$1/;
}
print $line;
}
} else {
($fh, $ctx) = command_output_pipe('blame', '-p', @_, 'HEAD',
'--', $path);
my ($sha1);
my %authors;
while (my $line = <$fh>) {
if ($line =~ /^([[:xdigit:]]{40})\s\d+\s\d+/) {
$sha1 = $1;
(undef, $rev, undef) = ::cmt_metadata($1);
$rev = '0' if (!$rev);
}
elsif ($line =~ /^author (.*)/) {
$authors{$rev} = $1;
$authors{$rev} =~ s/\s/_/g;
}
elsif ($line =~ /^\t(.*)$/) {
printf("%6s %10s %s\n", $rev, $authors{$rev}, $1);
}
}
print $line;
}
command_close_pipe($fh, $ctx);
}

View File

@@ -44,9 +44,9 @@ endif
all:: gitk-wish $(ALL_MSGFILES)
install:: all
$(INSTALL) gitk-wish '$(DESTDIR_SQ)$(bindir_SQ)'/gitk
$(INSTALL) -d '$(DESTDIR_SQ)$(msgsdir_SQ)'
$(foreach p,$(ALL_MSGFILES), $(INSTALL) $p '$(DESTDIR_SQ)$(msgsdir_SQ)' &&) true
$(INSTALL) -m 755 gitk-wish '$(DESTDIR_SQ)$(bindir_SQ)'/gitk
$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(msgsdir_SQ)'
$(foreach p,$(ALL_MSGFILES), $(INSTALL) -m 644 $p '$(DESTDIR_SQ)$(msgsdir_SQ)' &&) true
uninstall::
$(foreach p,$(ALL_MSGFILES), $(RM) '$(DESTDIR_SQ)$(msgsdir_SQ)'/$(notdir $p) &&) true

File diff suppressed because it is too large Load Diff

890
gitk-git/gitk-git/po/es.po Normal file
View File

@@ -0,0 +1,890 @@
# Translation of gitk
# Copyright (C) 2005-2008 Santiago Gala
# This file is distributed under the same license as the gitk package.
# Santiago Gala <santiago.gala@gmail.com>, 2008.
#
#
msgid ""
msgstr ""
"Project-Id-Version: gitk\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2008-03-13 17:29+0100\n"
"PO-Revision-Date: 2008-03-25 11:20+0100\n"
"Last-Translator: Santiago Gala <santiago.gala@gmail.com>\n"
"Language-Team: Spanish\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: gitk:111
msgid "Error executing git rev-list:"
msgstr "Error al ejecutar git rev-list:"
#: gitk:124
msgid "Reading"
msgstr "Leyendo"
#: gitk:151 gitk:2191
msgid "Reading commits..."
msgstr "Leyendo revisiones..."
#: gitk:275
msgid "Can't parse git log output:"
msgstr "Error analizando la salida de git log:"
#: gitk:386 gitk:2195
msgid "No commits selected"
msgstr "No se seleccionaron revisiones"
#: gitk:500
msgid "No commit information available"
msgstr "Falta información sobre las revisiones"
#: gitk:599 gitk:621 gitk:1955 gitk:6423 gitk:7923 gitk:8082
msgid "OK"
msgstr "Aceptar"
#: gitk:623 gitk:1956 gitk:6107 gitk:6178 gitk:6275 gitk:6321 gitk:6425
#: gitk:7924 gitk:8083
msgid "Cancel"
msgstr "Cancelar"
#: gitk:661
msgid "File"
msgstr "Archivo"
#: gitk:663
msgid "Update"
msgstr "Actualizar"
#: gitk:664
msgid "Reread references"
msgstr "Releer referencias"
#: gitk:665
msgid "List references"
msgstr "Lista de referencias"
#: gitk:666
msgid "Quit"
msgstr "Salir"
#: gitk:668
msgid "Edit"
msgstr "Editar"
#: gitk:669
msgid "Preferences"
msgstr "Preferencias"
#: gitk:672 gitk:1892
msgid "View"
msgstr "Vista"
#: gitk:673
msgid "New view..."
msgstr "Nueva vista..."
#: gitk:674 gitk:2133 gitk:8722
msgid "Edit view..."
msgstr "Modificar vista..."
#: gitk:676 gitk:2134 gitk:8723
msgid "Delete view"
msgstr "Eliminar vista"
#: gitk:678
msgid "All files"
msgstr "Todos los archivos"
#: gitk:682
msgid "Help"
msgstr "Ayuda"
#: gitk:683 gitk:1317
msgid "About gitk"
msgstr "Acerca de gitk"
#: gitk:684
msgid "Key bindings"
msgstr "Combinaciones de teclas"
#: gitk:741
msgid "SHA1 ID: "
msgstr "SHA1 ID: "
#: gitk:791
msgid "Find"
msgstr "Buscar"
#: gitk:792
msgid "next"
msgstr "<<"
#: gitk:793
msgid "prev"
msgstr ">>"
#: gitk:794
msgid "commit"
msgstr "revisión"
#: gitk:797 gitk:799 gitk:2356 gitk:2379 gitk:2403 gitk:4306 gitk:4369
msgid "containing:"
msgstr "que contiene:"
#: gitk:800 gitk:1778 gitk:1783 gitk:2431
msgid "touching paths:"
msgstr "que modifica la ruta:"
#: gitk:801 gitk:2436
msgid "adding/removing string:"
msgstr "que añade/elimina cadena:"
#: gitk:810 gitk:812
msgid "Exact"
msgstr "Exacto"
#: gitk:812 gitk:2514 gitk:4274
msgid "IgnCase"
msgstr "NoMayús"
#: gitk:812 gitk:2405 gitk:2512 gitk:4270
msgid "Regexp"
msgstr "Regex"
#: gitk:814 gitk:815 gitk:2533 gitk:2563 gitk:2570 gitk:4380 gitk:4436
msgid "All fields"
msgstr "Todos los campos"
#: gitk:815 gitk:2531 gitk:2563 gitk:4336
msgid "Headline"
msgstr "Título"
#: gitk:816 gitk:2531 gitk:4336 gitk:4436 gitk:4827
msgid "Comments"
msgstr "Comentarios"
#: gitk:816 gitk:2531 gitk:2535 gitk:2570 gitk:4336 gitk:4763 gitk:5956
#: gitk:5971
msgid "Author"
msgstr "Autor"
#: gitk:816 gitk:2531 gitk:4336 gitk:4765
msgid "Committer"
msgstr ""
#: gitk:845
msgid "Search"
msgstr "Buscar"
#: gitk:852
msgid "Diff"
msgstr "Diferencia"
#: gitk:854
msgid "Old version"
msgstr "Versión antigua"
#: gitk:856
msgid "New version"
msgstr "Versión nueva"
#: gitk:858
msgid "Lines of context"
msgstr "Líneas de contexto"
#: gitk:868
msgid "Ignore space change"
msgstr "Ignora cambios de espaciado"
#: gitk:926
msgid "Patch"
msgstr "Parche"
#: gitk:928
msgid "Tree"
msgstr "Árbol"
#: gitk:1053 gitk:1068 gitk:6022
msgid "Diff this -> selected"
msgstr "Diferencia de esta -> seleccionada"
#: gitk:1055 gitk:1070 gitk:6023
msgid "Diff selected -> this"
msgstr "Diferencia de seleccionada -> esta"
#: gitk:1057 gitk:1072 gitk:6024
msgid "Make patch"
msgstr "Crear patch"
#: gitk:1058 gitk:6162
msgid "Create tag"
msgstr "Crear etiqueta"
#: gitk:1059 gitk:6255
msgid "Write commit to file"
msgstr "Escribir revisiones a archivo"
#: gitk:1060 gitk:6309
msgid "Create new branch"
msgstr "Crear nueva rama"
#: gitk:1061
msgid "Cherry-pick this commit"
msgstr "Añadir esta revisión a la rama actual (cherry-pick)"
#: gitk:1063
msgid "Reset HEAD branch to here"
msgstr "Traer la rama HEAD aquí"
#: gitk:1079
msgid "Check out this branch"
msgstr "Cambiar a esta rama"
#: gitk:1081
msgid "Remove this branch"
msgstr "Eliminar esta rama"
#: gitk:1087
msgid "Highlight this too"
msgstr "Seleccionar también"
#: gitk:1089
msgid "Highlight this only"
msgstr "Seleccionar sólo"
#: gitk:1318
msgid ""
"\n"
"Gitk - a commit viewer for git\n"
"\n"
"Copyright © 2005-2006 Paul Mackerras\n"
"\n"
"Use and redistribute under the terms of the GNU General Public License"
msgstr ""
"\n"
"Gitk - un visualizador de revisiones para git\n"
"\n"
"Copyright © 2005-2006 Paul Mackerras\n"
"\n"
"Uso y redistribución permitidos según los términos de la Licencia Pública General de "
"GNU (GNU GPL)"
#: gitk:1326 gitk:1387 gitk:6581
msgid "Close"
msgstr "Cerrar"
#: gitk:1345
msgid "Gitk key bindings"
msgstr "Combinaciones de tecla de Gitk"
#: gitk:1347
msgid "Gitk key bindings:"
msgstr "Combinaciones de tecla de Gitk:"
#: gitk:1349
#, tcl-format
msgid "<%s-Q>\t\tQuit"
msgstr "<%s-Q>\t\tSalir"
#: gitk:1350
msgid "<Home>\t\tMove to first commit"
msgstr "<Home>\t\tIr a la primera revisión"
#: gitk:1351
msgid "<End>\t\tMove to last commit"
msgstr "<End>\t\tIr a la última revisión"
#: gitk:1352
msgid "<Up>, p, i\tMove up one commit"
msgstr "<Up>, p, i\tSubir una revisión"
#: gitk:1353
msgid "<Down>, n, k\tMove down one commit"
msgstr "<Down>, n, k\tBajar una revisión"
#: gitk:1354
msgid "<Left>, z, j\tGo back in history list"
msgstr "<Left>, z, j\tRetroceder en la historia"
#: gitk:1355
msgid "<Right>, x, l\tGo forward in history list"
msgstr "<Right>, x, l\tAvanzar en la historia"
#: gitk:1356
msgid "<PageUp>\tMove up one page in commit list"
msgstr "<PageUp>\tSubir una página en la lista de revisiones"
#: gitk:1357
msgid "<PageDown>\tMove down one page in commit list"
msgstr "<PageDown>\tBajar una página en la lista de revisiones"
#: gitk:1358
#, tcl-format
msgid "<%s-Home>\tScroll to top of commit list"
msgstr "<%s-Home>\tDesplazarse al inicio de la lista de revisiones"
#: gitk:1359
#, tcl-format
msgid "<%s-End>\tScroll to bottom of commit list"
msgstr "<%s-End>\tDesplazarse al final de la lista de revisiones"
#: gitk:1360
#, tcl-format
msgid "<%s-Up>\tScroll commit list up one line"
msgstr "<%s-Up>\tDesplazar una línea hacia arriba la lista de revisiones"
#: gitk:1361
#, tcl-format
msgid "<%s-Down>\tScroll commit list down one line"
msgstr "<%s-Down>\tDesplazar una línea hacia abajo la lista de revisiones"
#: gitk:1362
#, tcl-format
msgid "<%s-PageUp>\tScroll commit list up one page"
msgstr "<%s-PageUp>\tDesplazar una página hacia arriba la lista de revisiones"
#: gitk:1363
#, tcl-format
msgid "<%s-PageDown>\tScroll commit list down one page"
msgstr "<%s-PageDown>\tDesplazar una página hacia abajo la lista de revisiones"
#: gitk:1364
msgid "<Shift-Up>\tFind backwards (upwards, later commits)"
msgstr "<Shift-Up>\tBuscar hacia atrás (arriba, revisiones siguientes)"
#: gitk:1365
msgid "<Shift-Down>\tFind forwards (downwards, earlier commits)"
msgstr "<Shift-Down>\tBuscar hacia adelante (abajo, revisiones anteriores)"
#: gitk:1366
msgid "<Delete>, b\tScroll diff view up one page"
msgstr "<Delete>, b\tDesplaza hacia arriba una página la vista de diferencias"
#: gitk:1367
msgid "<Backspace>\tScroll diff view up one page"
msgstr "<Backspace>\tDesplaza hacia arriba una página la vista de diferencias"
#: gitk:1368
msgid "<Space>\t\tScroll diff view down one page"
msgstr "<Space>\t\tDesplaza hacia abajo una página la vista de diferencias"
#: gitk:1369
msgid "u\t\tScroll diff view up 18 lines"
msgstr "u\t\tDesplaza hacia arriba 18 líneas la vista de diferencias"
#: gitk:1370
msgid "d\t\tScroll diff view down 18 lines"
msgstr "d\t\tDesplaza hacia abajo 18 líneas la vista de diferencias"
#: gitk:1371
#, tcl-format
msgid "<%s-F>\t\tFind"
msgstr "<%s-F>\t\tBuscar"
#: gitk:1372
#, tcl-format
msgid "<%s-G>\t\tMove to next find hit"
msgstr "<%s-G>\t\tBuscar el siguiente"
#: gitk:1373
msgid "<Return>\tMove to next find hit"
msgstr "<Return>\tBuscar el siguiente"
#: gitk:1374
msgid "/\t\tMove to next find hit, or redo find"
msgstr "/\t\tBuscar el siguiente, o reiniciar la búsqueda"
#: gitk:1375
msgid "?\t\tMove to previous find hit"
msgstr "?\t\tBuscar el anterior"
#: gitk:1376
msgid "f\t\tScroll diff view to next file"
msgstr "f\t\tDesplazar la vista de diferencias al archivo siguiente"
#: gitk:1377
#, tcl-format
msgid "<%s-S>\t\tSearch for next hit in diff view"
msgstr "<%s-S>\t\tBuscar siguiente en la vista de diferencias"
#: gitk:1378
#, tcl-format
msgid "<%s-R>\t\tSearch for previous hit in diff view"
msgstr "<%s-R>\t\tBuscar anterior en la vista de diferencias"
#: gitk:1379
#, tcl-format
msgid "<%s-KP+>\tIncrease font size"
msgstr "<%s-KP+>\tAumentar tamaño del texto"
#: gitk:1380
#, tcl-format
msgid "<%s-plus>\tIncrease font size"
msgstr "<%s-plus>\tAumentar tamaño del texto"
#: gitk:1381
#, tcl-format
msgid "<%s-KP->\tDecrease font size"
msgstr "<%s-KP->\tDisminuir tamaño del texto"
#: gitk:1382
#, tcl-format
msgid "<%s-minus>\tDecrease font size"
msgstr "<%s-minus>\tDisminuir tamaño del texto"
#: gitk:1383
msgid "<F5>\t\tUpdate"
msgstr "<F5>\t\tActualizar"
#: gitk:1896
msgid "Gitk view definition"
msgstr "Definición de vistas de Gitk"
#: gitk:1921
msgid "Name"
msgstr "Nombre"
#: gitk:1924
msgid "Remember this view"
msgstr "Recordar esta vista"
#: gitk:1928
msgid "Commits to include (arguments to git rev-list):"
msgstr "Revisiones a incluir (argumentos a git rev-list):"
#: gitk:1935
msgid "Command to generate more commits to include:"
msgstr "Comando que genera más revisiones a incluir:"
#: gitk:1942
msgid "Enter files and directories to include, one per line:"
msgstr "Introducir archivos y directorios a incluir, uno por línea:"
#: gitk:1989
msgid "Error in commit selection arguments:"
msgstr "Error en los argumentos de selección de las revisiones:"
#: gitk:2043 gitk:2127 gitk:2583 gitk:2597 gitk:3781 gitk:8688 gitk:8689
msgid "None"
msgstr "Ninguno"
#: gitk:2531 gitk:4336 gitk:5958 gitk:5973
msgid "Date"
msgstr "Fecha"
#: gitk:2531 gitk:4336
msgid "CDate"
msgstr "Fecha de creación"
#: gitk:2680 gitk:2685
msgid "Descendant"
msgstr "Descendiente"
#: gitk:2681
msgid "Not descendant"
msgstr "No descendiente"
#: gitk:2688 gitk:2693
msgid "Ancestor"
msgstr "Antepasado"
#: gitk:2689
msgid "Not ancestor"
msgstr "No antepasado"
#: gitk:2924
msgid "Local changes checked in to index but not committed"
msgstr "Cambios locales añadidos al índice pero sin completar revisión"
#: gitk:2954
msgid "Local uncommitted changes, not checked in to index"
msgstr "Cambios locales sin añadir al índice"
#: gitk:4305
msgid "Searching"
msgstr "Buscando"
#: gitk:4767
msgid "Tags:"
msgstr "Etiquetas:"
#: gitk:4784 gitk:4790 gitk:5951
msgid "Parent"
msgstr "Padre"
#: gitk:4795
msgid "Child"
msgstr "Hija"
#: gitk:4804
msgid "Branch"
msgstr "Rama"
#: gitk:4807
msgid "Follows"
msgstr "Sigue-a"
#: gitk:4810
msgid "Precedes"
msgstr "Precede-a"
#: gitk:5093
msgid "Error getting merge diffs:"
msgstr "Error al leer las diferencias de fusión:"
#: gitk:5778
msgid "Goto:"
msgstr "Ir a:"
#: gitk:5780
msgid "SHA1 ID:"
msgstr "SHA1 ID:"
#: gitk:5805
#, tcl-format
msgid "Short SHA1 id %s is ambiguous"
msgstr "La id SHA1 abreviada %s es ambigua"
#: gitk:5817
#, tcl-format
msgid "SHA1 id %s is not known"
msgstr "La id SHA1 %s es desconocida"
#: gitk:5819
#, tcl-format
msgid "Tag/Head %s is not known"
msgstr "La etiqueta/rama %s es deconocida"
#: gitk:5961
msgid "Children"
msgstr "Hijas"
#: gitk:6018
#, tcl-format
msgid "Reset %s branch to here"
msgstr "Poner la rama %s en esta revisión"
#: gitk:6049
msgid "Top"
msgstr "Origen"
#: gitk:6050
msgid "From"
msgstr "De"
#: gitk:6055
msgid "To"
msgstr "A"
#: gitk:6078
msgid "Generate patch"
msgstr "Generar parche"
#: gitk:6080
msgid "From:"
msgstr "De:"
#: gitk:6089
msgid "To:"
msgstr "Para:"
#: gitk:6098
msgid "Reverse"
msgstr "Invertir"
#: gitk:6100 gitk:6269
msgid "Output file:"
msgstr "Escribir a archivo:"
#: gitk:6106
msgid "Generate"
msgstr "Generar"
#: gitk:6142
msgid "Error creating patch:"
msgstr "Error en la creación del parche:"
#: gitk:6164 gitk:6257 gitk:6311
msgid "ID:"
msgstr "ID:"
#: gitk:6173
msgid "Tag name:"
msgstr "Nombre de etiqueta:"
#: gitk:6177 gitk:6320
msgid "Create"
msgstr "Crear"
#: gitk:6192
msgid "No tag name specified"
msgstr "No se ha especificado etiqueta"
#: gitk:6196
#, tcl-format
msgid "Tag \"%s\" already exists"
msgstr "La etiqueta \"%s\" ya existe"
#: gitk:6202
msgid "Error creating tag:"
msgstr "Error al crear la etiqueta:"
#: gitk:6266
msgid "Command:"
msgstr "Comando:"
#: gitk:6274
msgid "Write"
msgstr "Escribir"
#: gitk:6290
msgid "Error writing commit:"
msgstr "Error al escribir revisión:"
#: gitk:6316
msgid "Name:"
msgstr "Nombre:"
#: gitk:6335
msgid "Please specify a name for the new branch"
msgstr "Especifique un nombre para la nueva rama"
#: gitk:6364
#, tcl-format
msgid "Commit %s is already included in branch %s -- really re-apply it?"
msgstr "La revisión %s ya está incluida en la rama %s -- ¿Volver a aplicarla?"
#: gitk:6369
msgid "Cherry-picking"
msgstr "Eligiendo revisiones (cherry-picking)"
#: gitk:6381
msgid "No changes committed"
msgstr "No se han guardado cambios"
#: gitk:6404
msgid "Confirm reset"
msgstr "Confirmar git reset"
#: gitk:6406
#, tcl-format
msgid "Reset branch %s to %s?"
msgstr "¿Reponer la rama %s a %s?"
#: gitk:6410
msgid "Reset type:"
msgstr "Tipo de reposición:"
#: gitk:6414
msgid "Soft: Leave working tree and index untouched"
msgstr "Suave: No altera la copia de trabajo ni el índice"
#: gitk:6417
msgid "Mixed: Leave working tree untouched, reset index"
msgstr "Mixta: Actualiza el índice, no altera la copia de trabajo"
#: gitk:6420
msgid ""
"Hard: Reset working tree and index\n"
"(discard ALL local changes)"
msgstr ""
"Dura: Actualiza el índice y la copia de trabajo\n"
"(abandona TODAS las modificaciones locales)"
#: gitk:6436
msgid "Resetting"
msgstr "Reponiendo"
#: gitk:6493
msgid "Checking out"
msgstr "Creando copia de trabajo"
#: gitk:6523
msgid "Cannot delete the currently checked-out branch"
msgstr "No se puede borrar la rama actual"
#: gitk:6529
#, tcl-format
msgid ""
"The commits on branch %s aren't on any other branch.\n"
"Really delete branch %s?"
msgstr ""
"Las revisiones de la rama %s no están presentes en otras ramas.\n"
"¿Borrar la rama %s?"
#: gitk:6560
#, tcl-format
msgid "Tags and heads: %s"
msgstr "Etiquetas y ramas: %s"
#: gitk:6574
msgid "Filter"
msgstr "Filtro"
#: gitk:6868
msgid ""
"Error reading commit topology information; branch and preceding/following "
"tag information will be incomplete."
msgstr ""
"Error al leer la topología de revisiones: la información sobre "
"las ramas y etiquetas precedentes y siguientes será incompleta."
#: gitk:7852
msgid "Tag"
msgstr "Etiqueta"
#: gitk:7852
msgid "Id"
msgstr "Id"
#: gitk:7892
msgid "Gitk font chooser"
msgstr "Selector de tipografías gitk"
#: gitk:7909
msgid "B"
msgstr "B"
#: gitk:7912
msgid "I"
msgstr "I"
#: gitk:8005
msgid "Gitk preferences"
msgstr "Preferencias de gitk"
#: gitk:8006
msgid "Commit list display options"
msgstr "Opciones de visualización de la lista de revisiones"
#: gitk:8009
msgid "Maximum graph width (lines)"
msgstr "Ancho máximo del gráfico (en líneas)"
#: gitk:8013
#, tcl-format
msgid "Maximum graph width (% of pane)"
msgstr "Ancho máximo del gráfico (en % del panel)"
#: gitk:8018
msgid "Show local changes"
msgstr "Mostrar cambios locales"
#: gitk:8023
msgid "Auto-select SHA1"
msgstr "Seleccionar automáticamente SHA1 hash"
#: gitk:8028
msgid "Diff display options"
msgstr "Opciones de visualización de diferencias"
#: gitk:8030
msgid "Tab spacing"
msgstr "Espaciado de tabulador"
#: gitk:8034
msgid "Display nearby tags"
msgstr "Mostrar etiquetas cercanas"
#: gitk:8039
msgid "Limit diffs to listed paths"
msgstr "Limitar las diferencias a las rutas seleccionadas"
#: gitk:8044
msgid "Colors: press to choose"
msgstr "Colores: pulse para seleccionar"
#: gitk:8047
msgid "Background"
msgstr "Fondo"
#: gitk:8051
msgid "Foreground"
msgstr "Primer plano"
#: gitk:8055
msgid "Diff: old lines"
msgstr "Diff: líneas viejas"
#: gitk:8060
msgid "Diff: new lines"
msgstr "Diff: líneas nuevas"
#: gitk:8065
msgid "Diff: hunk header"
msgstr "Diff: cabecera de fragmento"
#: gitk:8071
msgid "Select bg"
msgstr "Color de fondo de la selección"
#: gitk:8075
msgid "Fonts: press to choose"
msgstr "Tipografías: pulse para elegir"
#: gitk:8077
msgid "Main font"
msgstr "Tipografía principal"
#: gitk:8078
msgid "Diff display font"
msgstr "Tipografía para diferencias"
#: gitk:8079
msgid "User interface font"
msgstr "Tipografía para interfaz de usuario"
#: gitk:8095
#, tcl-format
msgid "Gitk: choose color for %s"
msgstr "Gitk: elegir color para %s"
#: gitk:8476
msgid ""
"Sorry, gitk cannot run with this version of Tcl/Tk.\n"
" Gitk requires at least Tcl/Tk 8.4."
msgstr ""
"Esta versión de Tcl/Tk es demasiado antigua.\n"
" Gitk requiere Tcl/Tk versión 8.4 o superior."
#: gitk:8565
msgid "Cannot find a git repository here."
msgstr "No hay un repositorio git aquí."
#: gitk:8569
#, tcl-format
msgid "Cannot find the git directory \"%s\"."
msgstr "No hay directorio git \"%s\"."
#: gitk:8612
#, tcl-format
msgid "Ambiguous argument '%s': both revision and filename"
msgstr "Argumento ambiguo: '%s' es tanto una revisión como un nombre de archivo"
#: gitk:8624
msgid "Bad arguments to gitk:"
msgstr "Argumentos incorrectos a Gitk:"
#: gitk:8636
msgid "Couldn't get list of unmerged files:"
msgstr "Imposible obtener la lista de archivos pendientes de fusión:"
#: gitk:8652
msgid "No files selected: --merge specified but no files are unmerged."
msgstr ""
"No hay archivos seleccionados: se seleccionó la opción --merge pero no hay "
"archivos pendientes de fusión."
#: gitk:8655
msgid ""
"No files selected: --merge specified but no unmerged files are within file "
"limit."
msgstr ""
"No hay archivos seleccionados: se seleccionó la opción --merge pero los archivos "
"especificados no necesitan fusión."
#: gitk:8716
msgid "Command line"
msgstr "Línea de comandos"

File diff suppressed because it is too large Load Diff

887
gitk-git/po/sv.po Normal file
View File

@@ -0,0 +1,887 @@
# Swedish translation for gitk
# Copyright (C) 2005-2008 Paul Mackerras
# This file is distributed under the same license as the gitk package.
#
# Peter Karlsson <peter@softwolves.pp.se>, 2008.
msgid ""
msgstr ""
"Project-Id-Version: sv\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2008-03-14 15:03+0100\n"
"PO-Revision-Date: 2008-03-14 16:06CET-1\n"
"Last-Translator: Peter Karlsson <peter@softwolves.pp.se>\n"
"Language-Team: Swedish <sv@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit"
#: gitk:111
msgid "Error executing git rev-list:"
msgstr "Fel vid körning av git rev-list:"
#: gitk:124
msgid "Reading"
msgstr "Läser"
#: gitk:151 gitk:2191
msgid "Reading commits..."
msgstr "Läser incheckningar..."
#: gitk:275
msgid "Can't parse git log output:"
msgstr "Kan inte tolka utdata från git log:"
#: gitk:386 gitk:2195
msgid "No commits selected"
msgstr "Inga incheckningar markerade"
#: gitk:500
msgid "No commit information available"
msgstr "Ingen incheckningsinformation är tillgänglig"
#: gitk:599 gitk:621 gitk:1955 gitk:6423 gitk:7923 gitk:8082
msgid "OK"
msgstr "OK"
#: gitk:623 gitk:1956 gitk:6107 gitk:6178 gitk:6275 gitk:6321 gitk:6425
#: gitk:7924 gitk:8083
msgid "Cancel"
msgstr "Avbryt"
#: gitk:661
msgid "File"
msgstr "Arkiv"
#: gitk:663
msgid "Update"
msgstr "Uppdatera"
#: gitk:664
msgid "Reread references"
msgstr "Läs om referenser"
#: gitk:665
msgid "List references"
msgstr "Visa referenser"
#: gitk:666
msgid "Quit"
msgstr "Avsluta"
#: gitk:668
msgid "Edit"
msgstr "Redigera"
#: gitk:669
msgid "Preferences"
msgstr "Inställningar"
#: gitk:672 gitk:1892
msgid "View"
msgstr "Visa"
#: gitk:673
msgid "New view..."
msgstr "Ny vy..."
#: gitk:674 gitk:2133 gitk:8722
msgid "Edit view..."
msgstr "Ändra vy..."
#: gitk:676 gitk:2134 gitk:8723
msgid "Delete view"
msgstr "Ta bort vy"
#: gitk:678
msgid "All files"
msgstr "Alla filer"
#: gitk:682
msgid "Help"
msgstr "Hjälp"
#: gitk:683 gitk:1317
msgid "About gitk"
msgstr "Om gitk"
#: gitk:684
msgid "Key bindings"
msgstr "Tangentbordsbindningar"
#: gitk:741
msgid "SHA1 ID: "
msgstr "SHA1-id: "
#: gitk:791
msgid "Find"
msgstr "Sök"
#: gitk:792
msgid "next"
msgstr "nästa"
#: gitk:793
msgid "prev"
msgstr "föreg"
#: gitk:794
msgid "commit"
msgstr "incheckning"
#: gitk:797 gitk:799 gitk:2356 gitk:2379 gitk:2403 gitk:4306 gitk:4369
msgid "containing:"
msgstr "som innehåller:"
#: gitk:800 gitk:1778 gitk:1783 gitk:2431
msgid "touching paths:"
msgstr "som rör sökväg:"
#: gitk:801 gitk:2436
msgid "adding/removing string:"
msgstr "som lägger/till tar bort sträng:"
#: gitk:810 gitk:812
msgid "Exact"
msgstr "Exakt"
#: gitk:812 gitk:2514 gitk:4274
msgid "IgnCase"
msgstr "IgnVersaler"
#: gitk:812 gitk:2405 gitk:2512 gitk:4270
msgid "Regexp"
msgstr "Reg.uttr."
#: gitk:814 gitk:815 gitk:2533 gitk:2563 gitk:2570 gitk:4380 gitk:4436
msgid "All fields"
msgstr "Alla fält"
#: gitk:815 gitk:2531 gitk:2563 gitk:4336
msgid "Headline"
msgstr "Rubrik"
#: gitk:816 gitk:2531 gitk:4336 gitk:4436 gitk:4827
msgid "Comments"
msgstr "Kommentarer"
#: gitk:816 gitk:2531 gitk:2535 gitk:2570 gitk:4336 gitk:4763 gitk:5956
#: gitk:5971
msgid "Author"
msgstr "Författare"
#: gitk:816 gitk:2531 gitk:4336 gitk:4765
msgid "Committer"
msgstr "Incheckare"
#: gitk:845
msgid "Search"
msgstr "Sök"
#: gitk:852
msgid "Diff"
msgstr "Diff"
#: gitk:854
msgid "Old version"
msgstr "Gammal version"
#: gitk:856
msgid "New version"
msgstr "Ny version"
#: gitk:858
msgid "Lines of context"
msgstr "Rader sammanhang"
#: gitk:868
msgid "Ignore space change"
msgstr "Ignorera ändringar i blanksteg"
#: gitk:926
msgid "Patch"
msgstr "Patch"
#: gitk:928
msgid "Tree"
msgstr "Träd"
#: gitk:1053 gitk:1068 gitk:6022
msgid "Diff this -> selected"
msgstr "Diff denna -> markerad"
#: gitk:1055 gitk:1070 gitk:6023
msgid "Diff selected -> this"
msgstr "Diff markerad -> denna"
#: gitk:1057 gitk:1072 gitk:6024
msgid "Make patch"
msgstr "Skapa patch"
#: gitk:1058 gitk:6162
msgid "Create tag"
msgstr "Skapa tagg"
#: gitk:1059 gitk:6255
msgid "Write commit to file"
msgstr "Skriv incheckning till fil"
#: gitk:1060 gitk:6309
msgid "Create new branch"
msgstr "Skapa ny gren"
#: gitk:1061
msgid "Cherry-pick this commit"
msgstr "Plocka denna incheckning"
#: gitk:1063
msgid "Reset HEAD branch to here"
msgstr "Återställ HEAD-grenen hit"
#: gitk:1079
msgid "Check out this branch"
msgstr "Checka ut denna gren"
#: gitk:1081
msgid "Remove this branch"
msgstr "Ta bort denna gren"
#: gitk:1087
msgid "Highlight this too"
msgstr "Markera även detta"
#: gitk:1089
msgid "Highlight this only"
msgstr "Markera bara detta"
#: gitk:1318
msgid ""
"\n"
"Gitk - a commit viewer for git\n"
"\n"
"Copyright © 2005-2006 Paul Mackerras\n"
"\n"
"Use and redistribute under the terms of the GNU General Public License"
msgstr ""
"\n"
"Gitk - en incheckningsvisare för git\n"
"\n"
"Copyright © 2005-2006 Paul Mackerras\n"
"\n"
"Använd och vidareförmedla enligt villkoren i GNU General Public License"
#: gitk:1326 gitk:1387 gitk:6581
msgid "Close"
msgstr "Stäng"
#: gitk:1345
msgid "Gitk key bindings"
msgstr "Tangentbordsbindningar för Gitk"
#: gitk:1347
msgid "Gitk key bindings:"
msgstr "Tangentbordsbindningar för Gitk:"
#: gitk:1349
#, tcl-format
msgid "<%s-Q>\t\tQuit"
msgstr "<%s-Q>\t\tAvsluta"
#: gitk:1350
msgid "<Home>\t\tMove to first commit"
msgstr "<Home>\t\tGå till första incheckning"
#: gitk:1351
msgid "<End>\t\tMove to last commit"
msgstr "<End>\t\tGå till sista incheckning"
#: gitk:1352
msgid "<Up>, p, i\tMove up one commit"
msgstr "<Upp>, p, i\tGå en incheckning upp"
#: gitk:1353
msgid "<Down>, n, k\tMove down one commit"
msgstr "<Ned>, n, k\tGå en incheckning ned"
#: gitk:1354
msgid "<Left>, z, j\tGo back in history list"
msgstr "<Vänster>, z, j\tGå bakåt i historiken"
#: gitk:1355
msgid "<Right>, x, l\tGo forward in history list"
msgstr "<Höger>, x, l\tGå framåt i historiken"
#: gitk:1356
msgid "<PageUp>\tMove up one page in commit list"
msgstr "<PageUp>\tGå upp en sida i incheckningslistan"
#: gitk:1357
msgid "<PageDown>\tMove down one page in commit list"
msgstr "<PageDown>\tGå ned en sida i incheckningslistan"
#: gitk:1358
#, tcl-format
msgid "<%s-Home>\tScroll to top of commit list"
msgstr "<%s-Home>\tRulla till början av incheckningslistan"
#: gitk:1359
#, tcl-format
msgid "<%s-End>\tScroll to bottom of commit list"
msgstr "<%s-End>\tRulla till slutet av incheckningslistan"
#: gitk:1360
#, tcl-format
msgid "<%s-Up>\tScroll commit list up one line"
msgstr "<%s-Upp>\tRulla incheckningslistan upp ett steg"
#: gitk:1361
#, tcl-format
msgid "<%s-Down>\tScroll commit list down one line"
msgstr "<%s-Ned>\tRulla incheckningslistan ned ett steg"
#: gitk:1362
#, tcl-format
msgid "<%s-PageUp>\tScroll commit list up one page"
msgstr "<%s-PageUp>\tRulla incheckningslistan upp en sida"
#: gitk:1363
#, tcl-format
msgid "<%s-PageDown>\tScroll commit list down one page"
msgstr "<%s-PageDown>\tRulla incheckningslistan ned en sida"
#: gitk:1364
msgid "<Shift-Up>\tFind backwards (upwards, later commits)"
msgstr "<Skift-Upp>\tSök bakåt (uppåt, senare incheckningar)"
#: gitk:1365
msgid "<Shift-Down>\tFind forwards (downwards, earlier commits)"
msgstr "<Skift-Ned>\tSök framåt (nedåt, tidigare incheckningar)"
#: gitk:1366
msgid "<Delete>, b\tScroll diff view up one page"
msgstr "<Delete>, b\tRulla diffvisningen upp en sida"
#: gitk:1367
msgid "<Backspace>\tScroll diff view up one page"
msgstr "<Baksteg>\tRulla diffvisningen upp en sida"
#: gitk:1368
msgid "<Space>\t\tScroll diff view down one page"
msgstr "<Blanksteg>\tRulla diffvisningen ned en sida"
#: gitk:1369
msgid "u\t\tScroll diff view up 18 lines"
msgstr "u\t\tRulla diffvisningen upp 18 rader"
#: gitk:1370
msgid "d\t\tScroll diff view down 18 lines"
msgstr "d\t\tRulla diffvisningen ned 18 rader"
#: gitk:1371
#, tcl-format
msgid "<%s-F>\t\tFind"
msgstr "<%s-F>\t\tSök"
#: gitk:1372
#, tcl-format
msgid "<%s-G>\t\tMove to next find hit"
msgstr "<%s-G>\t\tGå till nästa sökträff"
#: gitk:1373
msgid "<Return>\tMove to next find hit"
msgstr "<Return>\t\tGå till nästa sökträff"
#: gitk:1374
msgid "/\t\tMove to next find hit, or redo find"
msgstr "/\t\tGå till nästa sökträff, eller sök på nytt"
#: gitk:1375
msgid "?\t\tMove to previous find hit"
msgstr "?\t\tGå till föregående sökträff"
#: gitk:1376
msgid "f\t\tScroll diff view to next file"
msgstr "f\t\tRulla diffvisningen till nästa fil"
#: gitk:1377
#, tcl-format
msgid "<%s-S>\t\tSearch for next hit in diff view"
msgstr "<%s-S>\t\tGå till nästa sökträff i diffvisningen"
#: gitk:1378
#, tcl-format
msgid "<%s-R>\t\tSearch for previous hit in diff view"
msgstr "<%s-R>\t\tGå till föregående sökträff i diffvisningen"
#: gitk:1379
#, tcl-format
msgid "<%s-KP+>\tIncrease font size"
msgstr "<%s-Num+>\tÖka teckenstorlek"
#: gitk:1380
#, tcl-format
msgid "<%s-plus>\tIncrease font size"
msgstr "<%s-plus>\tÖka teckenstorlek"
#: gitk:1381
#, tcl-format
msgid "<%s-KP->\tDecrease font size"
msgstr "<%s-Num->\tMinska teckenstorlek"
#: gitk:1382
#, tcl-format
msgid "<%s-minus>\tDecrease font size"
msgstr "<%s-minus>\tMinska teckenstorlek"
#: gitk:1383
msgid "<F5>\t\tUpdate"
msgstr "<F5>\t\tUppdatera"
#: gitk:1896
msgid "Gitk view definition"
msgstr "Definition av Gitk-vy"
#: gitk:1921
msgid "Name"
msgstr "Namn"
#: gitk:1924
msgid "Remember this view"
msgstr "Spara denna vy"
#: gitk:1928
msgid "Commits to include (arguments to git rev-list):"
msgstr "Incheckningar att ta med (argument till git rev-list):"
#: gitk:1935
msgid "Command to generate more commits to include:"
msgstr "Kommando för att generera fler incheckningar att ta med:"
#: gitk:1942
msgid "Enter files and directories to include, one per line:"
msgstr "Ange filer och kataloger att ta med, en per rad:"
#: gitk:1989
msgid "Error in commit selection arguments:"
msgstr "Fel i argument för val av incheckningar:"
#: gitk:2043 gitk:2127 gitk:2583 gitk:2597 gitk:3781 gitk:8688 gitk:8689
msgid "None"
msgstr "Inget"
#: gitk:2531 gitk:4336 gitk:5958 gitk:5973
msgid "Date"
msgstr "Datum"
#: gitk:2531 gitk:4336
msgid "CDate"
msgstr "Skapat datum"
#: gitk:2680 gitk:2685
msgid "Descendant"
msgstr "Avkomling"
#: gitk:2681
msgid "Not descendant"
msgstr "Inte avkomling"
#: gitk:2688 gitk:2693
msgid "Ancestor"
msgstr "Förfader"
#: gitk:2689
msgid "Not ancestor"
msgstr "Inte förfader"
#: gitk:2924
msgid "Local changes checked in to index but not committed"
msgstr "Lokala ändringar sparade i indexet men inte incheckade"
#: gitk:2954
msgid "Local uncommitted changes, not checked in to index"
msgstr "Lokala ändringar, ej sparade i indexet"
#: gitk:4305
msgid "Searching"
msgstr "Söker"
#: gitk:4767
msgid "Tags:"
msgstr "Taggar:"
#: gitk:4784 gitk:4790 gitk:5951
msgid "Parent"
msgstr "Förälder"
#: gitk:4795
msgid "Child"
msgstr "Barn"
#: gitk:4804
msgid "Branch"
msgstr "Gren"
#: gitk:4807
msgid "Follows"
msgstr "Följer"
#: gitk:4810
msgid "Precedes"
msgstr "Föregår"
#: gitk:5093
msgid "Error getting merge diffs:"
msgstr "Fel vid hämtning av sammanslagningsdiff:"
#: gitk:5778
msgid "Goto:"
msgstr "Gå till:"
#: gitk:5780
msgid "SHA1 ID:"
msgstr "SHA1-id:"
#: gitk:5805
#, tcl-format
msgid "Short SHA1 id %s is ambiguous"
msgstr "Förkortat SHA1-id %s är tvetydigt"
#: gitk:5817
#, tcl-format
msgid "SHA1 id %s is not known"
msgstr "SHA-id:t %s är inte känt"
#: gitk:5819
#, tcl-format
msgid "Tag/Head %s is not known"
msgstr "Tagg/huvud %s är okänt"
#: gitk:5961
msgid "Children"
msgstr "Barn"
#: gitk:6018
#, tcl-format
msgid "Reset %s branch to here"
msgstr "Återställ grenen %s hit"
#: gitk:6049
msgid "Top"
msgstr "Topp"
#: gitk:6050
msgid "From"
msgstr "Från"
#: gitk:6055
msgid "To"
msgstr "Till"
#: gitk:6078
msgid "Generate patch"
msgstr "Generera patch"
#: gitk:6080
msgid "From:"
msgstr "Från:"
#: gitk:6089
msgid "To:"
msgstr "Till:"
#: gitk:6098
msgid "Reverse"
msgstr "Vänd"
#: gitk:6100 gitk:6269
msgid "Output file:"
msgstr "Utdatafil:"
#: gitk:6106
msgid "Generate"
msgstr "Generera"
#: gitk:6142
msgid "Error creating patch:"
msgstr "Fel vid generering av patch:"
#: gitk:6164 gitk:6257 gitk:6311
msgid "ID:"
msgstr "Id:"
#: gitk:6173
msgid "Tag name:"
msgstr "Taggnamn:"
#: gitk:6177 gitk:6320
msgid "Create"
msgstr "Skapa"
#: gitk:6192
msgid "No tag name specified"
msgstr "Inget taggnamn angavs"
#: gitk:6196
#, tcl-format
msgid "Tag \"%s\" already exists"
msgstr "Taggen \"%s\" finns redan"
#: gitk:6202
msgid "Error creating tag:"
msgstr "Fel vid skapande av tagg:"
#: gitk:6266
msgid "Command:"
msgstr "Kommando:"
#: gitk:6274
msgid "Write"
msgstr "Skriv"
#: gitk:6290
msgid "Error writing commit:"
msgstr "Fel vid skrivning av incheckning:"
#: gitk:6316
msgid "Name:"
msgstr "Namn:"
#: gitk:6335
msgid "Please specify a name for the new branch"
msgstr "Ange ett namn för den nya grenen"
#: gitk:6364
#, tcl-format
msgid "Commit %s is already included in branch %s -- really re-apply it?"
msgstr "Incheckningen %s finns redan på grenen %s -- skall den verkligen appliceras på nytt?"
#: gitk:6369
msgid "Cherry-picking"
msgstr "Plockar"
#: gitk:6381
msgid "No changes committed"
msgstr "Inga ändringar incheckade"
#: gitk:6404
msgid "Confirm reset"
msgstr "Bekräfta återställning"
#: gitk:6406
#, tcl-format
msgid "Reset branch %s to %s?"
msgstr "Återställa grenen %s till %s?"
#: gitk:6410
msgid "Reset type:"
msgstr "Typ av återställning:"
#: gitk:6414
msgid "Soft: Leave working tree and index untouched"
msgstr "Mjuk: Rör inte utcheckning och index"
#: gitk:6417
msgid "Mixed: Leave working tree untouched, reset index"
msgstr "Blandad: Rör inte utcheckning, återställ index"
#: gitk:6420
msgid ""
"Hard: Reset working tree and index\n"
"(discard ALL local changes)"
msgstr ""
"Hård: Återställ utcheckning och index\n"
"(förkastar ALLA lokala ändringar)"
#: gitk:6436
msgid "Resetting"
msgstr "Återställer"
#: gitk:6493
msgid "Checking out"
msgstr "Checkar ut"
#: gitk:6523
msgid "Cannot delete the currently checked-out branch"
msgstr "Kan inte ta bort den just nu utcheckade grenen"
#: gitk:6529
#, tcl-format
msgid ""
"The commits on branch %s aren't on any other branch.\n"
"Really delete branch %s?"
msgstr ""
"Incheckningarna på grenen %s existerar inte på någon annan gren.\n"
"Vill du verkligen ta bort grenen %s?"
#: gitk:6560
#, tcl-format
msgid "Tags and heads: %s"
msgstr "Taggar och huvuden: %s"
#: gitk:6574
msgid "Filter"
msgstr "Filter"
#: gitk:6868
msgid ""
"Error reading commit topology information; branch and preceding/following "
"tag information will be incomplete."
msgstr ""
"Fel vid läsning av information om incheckningstopologi; information om "
"grenar och föregående/senare taggar kommer inte vara komplett."
#: gitk:7852
msgid "Tag"
msgstr "Tagg"
#: gitk:7852
msgid "Id"
msgstr "Id"
#: gitk:7892
msgid "Gitk font chooser"
msgstr "Teckensnittsväljare för Gitk"
#: gitk:7909
msgid "B"
msgstr "F"
#: gitk:7912
msgid "I"
msgstr "K"
#: gitk:8005
msgid "Gitk preferences"
msgstr "Inställningar för Gitk"
#: gitk:8006
msgid "Commit list display options"
msgstr "Alternativ för incheckningslistvy"
#: gitk:8009
msgid "Maximum graph width (lines)"
msgstr "Maximal grafbredd (rader)"
#: gitk:8013
#, tcl-format
msgid "Maximum graph width (% of pane)"
msgstr "Maximal grafbredd (% av ruta)"
#: gitk:8018
msgid "Show local changes"
msgstr "Visa lokala ändringar"
#: gitk:8023
msgid "Auto-select SHA1"
msgstr "Välj SHA1 automatiskt"
#: gitk:8028
msgid "Diff display options"
msgstr "Alternativ för diffvy"
#: gitk:8030
msgid "Tab spacing"
msgstr "Blanksteg för tabulatortecken"
#: gitk:8034
msgid "Display nearby tags"
msgstr "Visa närliggande taggar"
#: gitk:8039
msgid "Limit diffs to listed paths"
msgstr "Begränsa diff till listade sökvägar"
#: gitk:8044
msgid "Colors: press to choose"
msgstr "Färger: tryck för att välja"
#: gitk:8047
msgid "Background"
msgstr "Bakgrund"
#: gitk:8051
msgid "Foreground"
msgstr "Förgrund"
#: gitk:8055
msgid "Diff: old lines"
msgstr "Diff: gamla rader"
#: gitk:8060
msgid "Diff: new lines"
msgstr "Diff: nya rader"
#: gitk:8065
msgid "Diff: hunk header"
msgstr "Diff: delhuvud"
#: gitk:8071
msgid "Select bg"
msgstr "Markerad bakgrund"
#: gitk:8075
msgid "Fonts: press to choose"
msgstr "Teckensnitt: tryck för att välja"
#: gitk:8077
msgid "Main font"
msgstr "Huvudteckensnitt"
#: gitk:8078
msgid "Diff display font"
msgstr "Teckensnitt för diffvisning"
#: gitk:8079
msgid "User interface font"
msgstr "Teckensnitt för användargränssnitt"
#: gitk:8095
#, tcl-format
msgid "Gitk: choose color for %s"
msgstr "Gitk: välj färg för %s"
#: gitk:8476
msgid ""
"Sorry, gitk cannot run with this version of Tcl/Tk.\n"
" Gitk requires at least Tcl/Tk 8.4."
msgstr ""
"Gitk kan tyvärr inte köra med denna version av Tcl/Tk.\n"
" Gitk kräver åtminstone Tcl/Tk 8.4."
#: gitk:8565
msgid "Cannot find a git repository here."
msgstr "Hittar inget gitk-arkiv här."
#: gitk:8569
#, tcl-format
msgid "Cannot find the git directory \"%s\"."
msgstr "Hittar inte git-katalogen \"%s\"."
#: gitk:8612
#, tcl-format
msgid "Ambiguous argument '%s': both revision and filename"
msgstr "Tvetydigt argument \"%s\": både revision och filnamn"
#: gitk:8624
msgid "Bad arguments to gitk:"
msgstr "Felaktiga argument till gitk:"
#: gitk:8636
msgid "Couldn't get list of unmerged files:"
msgstr "Kunde inta hämta lista över ej sammanslagna filer:"
#: gitk:8652
msgid "No files selected: --merge specified but no files are unmerged."
msgstr "Inga filer valdes: --merge angavs men det finns inga filer som inte har slagits samman."
#: gitk:8655
msgid ""
"No files selected: --merge specified but no unmerged files are within file "
"limit."
msgstr ""
"Inga filer valdes: --merge angavs men det finns inga filer inom "
"filbegränsningen."
#: gitk:8716
msgid "Command line"
msgstr "Kommandorad"

View File

@@ -464,6 +464,14 @@ a.rss_logo:hover {
background-color: #ee5500;
}
a.rss_logo.generic {
background-color: #ff8800;
}
a.rss_logo.generic:hover {
background-color: #ee7700;
}
span.refs span {
padding: 0px 4px;
font-size: 70%;

View File

@@ -592,7 +592,7 @@ exit;
## ======================================================================
## action links
sub href(%) {
sub href (%) {
my %params = @_;
# default is to use -absolute url() i.e. $my_uri
my $href = $params{-full} ? $my_url : $my_uri;
@@ -1448,6 +1448,46 @@ sub format_snapshot_links {
}
}
## ......................................................................
## functions returning values to be passed, perhaps after some
## transformation, to other functions; e.g. returning arguments to href()
# returns hash to be passed to href to generate gitweb URL
# in -title key it returns description of link
sub get_feed_info {
my $format = shift || 'Atom';
my %res = (action => lc($format));
# feed links are possible only for project views
return unless (defined $project);
# some views should link to OPML, or to generic project feed,
# or don't have specific feed yet (so they should use generic)
return if ($action =~ /^(?:tags|heads|forks|tag|search)$/x);
my $branch;
# branches refs uses 'refs/heads/' prefix (fullname) to differentiate
# from tag links; this also makes possible to detect branch links
if ((defined $hash_base && $hash_base =~ m!^refs/heads/(.*)$!) ||
(defined $hash && $hash =~ m!^refs/heads/(.*)$!)) {
$branch = $1;
}
# find log type for feed description (title)
my $type = 'log';
if (defined $file_name) {
$type = "history of $file_name";
$type .= "/" if ($action eq 'tree');
$type .= " on '$branch'" if (defined $branch);
} else {
$type = "log of $branch" if (defined $branch);
}
$res{-title} = $type;
$res{'hash'} = (defined $branch ? "refs/heads/$branch" : undef);
$res{'file_name'} = $file_name;
return %res;
}
## ----------------------------------------------------------------------
## git utility subroutines, invoking git commands
@@ -2510,30 +2550,49 @@ EOF
}
}
if (defined $project) {
printf('<link rel="alternate" title="%s log RSS feed" '.
'href="%s" type="application/rss+xml" />'."\n",
esc_param($project), href(action=>"rss"));
printf('<link rel="alternate" title="%s log RSS feed (no merges)" '.
'href="%s" type="application/rss+xml" />'."\n",
esc_param($project), href(action=>"rss",
extra_options=>"--no-merges"));
printf('<link rel="alternate" title="%s log Atom feed" '.
'href="%s" type="application/atom+xml" />'."\n",
esc_param($project), href(action=>"atom"));
printf('<link rel="alternate" title="%s log Atom feed (no merges)" '.
'href="%s" type="application/atom+xml" />'."\n",
esc_param($project), href(action=>"atom",
extra_options=>"--no-merges"));
my %href_params = get_feed_info();
if (!exists $href_params{'-title'}) {
$href_params{'-title'} = 'log';
}
foreach my $format qw(RSS Atom) {
my $type = lc($format);
my %link_attr = (
'-rel' => 'alternate',
'-title' => "$project - $href_params{'-title'} - $format feed",
'-type' => "application/$type+xml"
);
$href_params{'action'} = $type;
$link_attr{'-href'} = href(%href_params);
print "<link ".
"rel=\"$link_attr{'-rel'}\" ".
"title=\"$link_attr{'-title'}\" ".
"href=\"$link_attr{'-href'}\" ".
"type=\"$link_attr{'-type'}\" ".
"/>\n";
$href_params{'extra_options'} = '--no-merges';
$link_attr{'-href'} = href(%href_params);
$link_attr{'-title'} .= ' (no merges)';
print "<link ".
"rel=\"$link_attr{'-rel'}\" ".
"title=\"$link_attr{'-title'}\" ".
"href=\"$link_attr{'-href'}\" ".
"type=\"$link_attr{'-type'}\" ".
"/>\n";
}
} else {
printf('<link rel="alternate" title="%s projects list" '.
'href="%s" type="text/plain; charset=utf-8"/>'."\n",
'href="%s" type="text/plain; charset=utf-8" />'."\n",
$site_name, href(project=>undef, action=>"project_index"));
printf('<link rel="alternate" title="%s projects feeds" '.
'href="%s" type="text/x-opml"/>'."\n",
'href="%s" type="text/x-opml" />'."\n",
$site_name, href(project=>undef, action=>"opml"));
}
if (defined $favicon) {
print qq(<link rel="shortcut icon" href="$favicon" type="image/png"/>\n);
print qq(<link rel="shortcut icon" href="$favicon" type="image/png" />\n);
}
print "</head>\n" .
@@ -2601,23 +2660,35 @@ EOF
}
sub git_footer_html {
my $feed_class = 'rss_logo';
print "<div class=\"page_footer\">\n";
if (defined $project) {
my $descr = git_get_project_description($project);
if (defined $descr) {
print "<div class=\"page_footer_text\">" . esc_html($descr) . "</div>\n";
}
print $cgi->a({-href => href(action=>"rss"),
-class => "rss_logo"}, "RSS") . " ";
print $cgi->a({-href => href(action=>"atom"),
-class => "rss_logo"}, "Atom") . "\n";
my %href_params = get_feed_info();
if (!%href_params) {
$feed_class .= ' generic';
}
$href_params{'-title'} ||= 'log';
foreach my $format qw(RSS Atom) {
$href_params{'action'} = lc($format);
print $cgi->a({-href => href(%href_params),
-title => "$href_params{'-title'} $format feed",
-class => $feed_class}, $format)."\n";
}
} else {
print $cgi->a({-href => href(project=>undef, action=>"opml"),
-class => "rss_logo"}, "OPML") . " ";
-class => $feed_class}, "OPML") . " ";
print $cgi->a({-href => href(project=>undef, action=>"project_index"),
-class => "rss_logo"}, "TXT") . "\n";
-class => $feed_class}, "TXT") . "\n";
}
print "</div>\n" ;
print "</div>\n"; # class="page_footer"
if (-f $site_footer) {
open (my $fd, $site_footer);

173
help.c
View File

@@ -12,10 +12,16 @@
#include "dir.h"
static struct man_viewer_list {
void (*exec)(const char *);
struct man_viewer_list *next;
char name[FLEX_ARRAY];
} *man_viewer_list;
static struct man_viewer_info_list {
struct man_viewer_info_list *next;
const char *info;
char name[FLEX_ARRAY];
} *man_viewer_info_list;
enum help_format {
HELP_FORMAT_MAN,
HELP_FORMAT_INFO,
@@ -54,6 +60,18 @@ static enum help_format parse_help_format(const char *format)
die("unrecognized help format '%s'", format);
}
static const char *get_man_viewer_info(const char *name)
{
struct man_viewer_info_list *viewer;
for (viewer = man_viewer_info_list; viewer; viewer = viewer->next)
{
if (!strcasecmp(name, viewer->name))
return viewer->info;
}
return NULL;
}
static int check_emacsclient_version(void)
{
struct strbuf buffer = STRBUF_INIT;
@@ -100,53 +118,142 @@ static int check_emacsclient_version(void)
return 0;
}
static void exec_woman_emacs(const char *page)
static void exec_woman_emacs(const char* path, const char *page)
{
if (!check_emacsclient_version()) {
/* This works only with emacsclient version >= 22. */
struct strbuf man_page = STRBUF_INIT;
if (!path)
path = "emacsclient";
strbuf_addf(&man_page, "(woman \"%s\")", page);
execlp("emacsclient", "emacsclient", "-e", man_page.buf, NULL);
execlp(path, "emacsclient", "-e", man_page.buf, NULL);
warning("failed to exec '%s': %s", path, strerror(errno));
}
}
static void exec_man_konqueror(const char *page)
static void exec_man_konqueror(const char* path, const char *page)
{
const char *display = getenv("DISPLAY");
if (display && *display) {
struct strbuf man_page = STRBUF_INIT;
const char *filename = "kfmclient";
/* It's simpler to launch konqueror using kfmclient. */
if (path) {
const char *file = strrchr(path, '/');
if (file && !strcmp(file + 1, "konqueror")) {
char *new = xstrdup(path);
char *dest = strrchr(new, '/');
/* strlen("konqueror") == strlen("kfmclient") */
strcpy(dest + 1, "kfmclient");
path = new;
}
if (file)
filename = file;
} else
path = "kfmclient";
strbuf_addf(&man_page, "man:%s(1)", page);
execlp("kfmclient", "kfmclient", "newTab", man_page.buf, NULL);
execlp(path, filename, "newTab", man_page.buf, NULL);
warning("failed to exec '%s': %s", path, strerror(errno));
}
}
static void exec_man_man(const char *page)
static void exec_man_man(const char* path, const char *page)
{
execlp("man", "man", page, NULL);
if (!path)
path = "man";
execlp(path, "man", page, NULL);
warning("failed to exec '%s': %s", path, strerror(errno));
}
static void do_add_man_viewer(void (*exec)(const char *))
static void exec_man_cmd(const char *cmd, const char *page)
{
struct strbuf shell_cmd = STRBUF_INIT;
strbuf_addf(&shell_cmd, "%s %s", cmd, page);
execl("/bin/sh", "sh", "-c", shell_cmd.buf, NULL);
warning("failed to exec '%s': %s", cmd, strerror(errno));
}
static void add_man_viewer(const char *name)
{
struct man_viewer_list **p = &man_viewer_list;
size_t len = strlen(name);
while (*p)
p = &((*p)->next);
*p = xmalloc(sizeof(**p));
(*p)->next = NULL;
(*p)->exec = exec;
*p = xcalloc(1, (sizeof(**p) + len + 1));
strncpy((*p)->name, name, len);
}
static int add_man_viewer(const char *value)
static int supported_man_viewer(const char *name, size_t len)
{
if (!strcasecmp(value, "man"))
do_add_man_viewer(exec_man_man);
else if (!strcasecmp(value, "woman"))
do_add_man_viewer(exec_woman_emacs);
else if (!strcasecmp(value, "konqueror"))
do_add_man_viewer(exec_man_konqueror);
else
warning("'%s': unsupported man viewer.", value);
return (!strncasecmp("man", name, len) ||
!strncasecmp("woman", name, len) ||
!strncasecmp("konqueror", name, len));
}
static void do_add_man_viewer_info(const char *name,
size_t len,
const char *value)
{
struct man_viewer_info_list *new = xcalloc(1, sizeof(*new) + len + 1);
strncpy(new->name, name, len);
new->info = xstrdup(value);
new->next = man_viewer_info_list;
man_viewer_info_list = new;
}
static int add_man_viewer_path(const char *name,
size_t len,
const char *value)
{
if (supported_man_viewer(name, len))
do_add_man_viewer_info(name, len, value);
else
warning("'%s': path for unsupported man viewer.\n"
"Please consider using 'man.<tool>.cmd' instead.",
name);
return 0;
}
static int add_man_viewer_cmd(const char *name,
size_t len,
const char *value)
{
if (supported_man_viewer(name, len))
warning("'%s': cmd for supported man viewer.\n"
"Please consider using 'man.<tool>.path' instead.",
name);
else
do_add_man_viewer_info(name, len, value);
return 0;
}
static int add_man_viewer_info(const char *var, const char *value)
{
const char *name = var + 4;
const char *subkey = strrchr(name, '.');
if (!subkey)
return error("Config with no key for man viewer: %s", name);
if (!strcmp(subkey, ".path")) {
if (!value)
return config_error_nonbool(var);
return add_man_viewer_path(name, subkey - name, value);
}
if (!strcmp(subkey, ".cmd")) {
if (!value)
return config_error_nonbool(var);
return add_man_viewer_cmd(name, subkey - name, value);
}
warning("'%s': unsupported man viewer sub key.", subkey);
return 0;
}
@@ -161,8 +268,12 @@ static int git_help_config(const char *var, const char *value)
if (!strcmp(var, "man.viewer")) {
if (!value)
return config_error_nonbool(var);
return add_man_viewer(value);
add_man_viewer(value);
return 0;
}
if (!prefixcmp(var, "man."))
return add_man_viewer_info(var, value);
return git_default_config(var, value);
}
@@ -481,6 +592,22 @@ static void setup_man_path(void)
strbuf_release(&new_path);
}
static void exec_viewer(const char *name, const char *page)
{
const char *info = get_man_viewer_info(name);
if (!strcasecmp(name, "man"))
exec_man_man(info, page);
else if (!strcasecmp(name, "woman"))
exec_woman_emacs(info, page);
else if (!strcasecmp(name, "konqueror"))
exec_man_konqueror(info, page);
else if (info)
exec_man_cmd(info, page);
else
warning("'%s': unknown man viewer.", name);
}
static void show_man_page(const char *git_cmd)
{
struct man_viewer_list *viewer;
@@ -489,9 +616,9 @@ static void show_man_page(const char *git_cmd)
setup_man_path();
for (viewer = man_viewer_list; viewer; viewer = viewer->next)
{
viewer->exec(page); /* will return when unable */
exec_viewer(viewer->name, page); /* will return when unable */
}
exec_man_man(page);
exec_viewer("man", page);
die("no man viewer handled the request");
}

View File

@@ -1759,15 +1759,15 @@ static int one_local_ref(const char *refname, const unsigned char *sha1, int fla
static void one_remote_ref(char *refname)
{
struct ref *ref;
unsigned char remote_sha1[20];
struct object *obj;
int len = strlen(refname) + 1;
if (http_fetch_ref(remote->url, refname + 5 /* "refs/" */,
remote_sha1) != 0) {
ref = alloc_ref_from_str(refname);
if (http_fetch_ref(remote->url, ref) != 0) {
fprintf(stderr,
"Unable to fetch ref %s from %s\n",
refname, remote->url);
free(ref);
return;
}
@@ -1775,18 +1775,15 @@ static void one_remote_ref(char *refname)
* Fetch a copy of the object if it doesn't exist locally - it
* may be required for updating server info later.
*/
if (remote->can_update_info_refs && !has_sha1_file(remote_sha1)) {
obj = lookup_unknown_object(remote_sha1);
if (remote->can_update_info_refs && !has_sha1_file(ref->old_sha1)) {
obj = lookup_unknown_object(ref->old_sha1);
if (obj) {
fprintf(stderr, " fetch %s for %s\n",
sha1_to_hex(remote_sha1), refname);
sha1_to_hex(ref->old_sha1), refname);
add_fetch_request(obj);
}
}
ref = xcalloc(1, sizeof(*ref) + len);
hashcpy(ref->old_sha1, remote_sha1);
memcpy(ref->name, refname, len);
*remote_tail = ref;
remote_tail = &ref->next;
}
@@ -1891,33 +1888,36 @@ static void mark_edges_uninteresting(struct commit_list *list)
static void add_remote_info_ref(struct remote_ls_ctx *ls)
{
struct strbuf *buf = (struct strbuf *)ls->userData;
unsigned char remote_sha1[20];
struct object *o;
int len;
char *ref_info;
struct ref *ref;
if (http_fetch_ref(remote->url, ls->dentry_name + 5 /* "refs/" */,
remote_sha1) != 0) {
ref = alloc_ref_from_str(ls->dentry_name);
if (http_fetch_ref(remote->url, ref) != 0) {
fprintf(stderr,
"Unable to fetch ref %s from %s\n",
ls->dentry_name, remote->url);
aborted = 1;
free(ref);
return;
}
o = parse_object(remote_sha1);
o = parse_object(ref->old_sha1);
if (!o) {
fprintf(stderr,
"Unable to parse object %s for remote ref %s\n",
sha1_to_hex(remote_sha1), ls->dentry_name);
sha1_to_hex(ref->old_sha1), ls->dentry_name);
aborted = 1;
free(ref);
return;
}
len = strlen(ls->dentry_name) + 42;
ref_info = xcalloc(len + 1, 1);
sprintf(ref_info, "%s %s\n",
sha1_to_hex(remote_sha1), ls->dentry_name);
sha1_to_hex(ref->old_sha1), ls->dentry_name);
fwrite_buffer(ref_info, 1, len, buf);
free(ref_info);
@@ -1932,6 +1932,7 @@ static void add_remote_info_ref(struct remote_ls_ctx *ls)
free(ref_info);
}
}
free(ref);
}
static void update_remote_info_refs(struct remote_lock *lock)

View File

@@ -888,10 +888,10 @@ static int fetch(struct walker *walker, unsigned char *sha1)
data->alt->base);
}
static int fetch_ref(struct walker *walker, char *ref, unsigned char *sha1)
static int fetch_ref(struct walker *walker, struct ref *ref)
{
struct walker_data *data = walker->data;
return http_fetch_ref(data->alt->base, ref, sha1);
return http_fetch_ref(data->alt->base, ref);
}
static void cleanup(struct walker *walker)

18
http.c
View File

@@ -589,8 +589,9 @@ static char *quote_ref_url(const char *base, const char *ref)
len += 2; /* extra two hex plus replacement % */
qref = xmalloc(len);
memcpy(qref, base, baselen);
memcpy(qref + baselen, "/refs/", 6);
for (cp = ref, dp = qref + baselen + 6; (ch = *cp) != 0; cp++) {
dp = qref + baselen;
*(dp++) = '/';
for (cp = ref; (ch = *cp) != 0; cp++) {
if (needs_quote(ch)) {
*dp++ = '%';
*dp++ = hex((ch >> 4) & 0xF);
@@ -604,7 +605,7 @@ static char *quote_ref_url(const char *base, const char *ref)
return qref;
}
int http_fetch_ref(const char *base, const char *ref, unsigned char *sha1)
int http_fetch_ref(const char *base, struct ref *ref)
{
char *url;
struct strbuf buffer = STRBUF_INIT;
@@ -612,7 +613,7 @@ int http_fetch_ref(const char *base, const char *ref, unsigned char *sha1)
struct slot_results results;
int ret;
url = quote_ref_url(base, ref);
url = quote_ref_url(base, ref->name);
slot = get_active_slot();
slot->results = &results;
curl_easy_setopt(slot->curl, CURLOPT_FILE, &buffer);
@@ -624,12 +625,15 @@ int http_fetch_ref(const char *base, const char *ref, unsigned char *sha1)
if (results.curl_result == CURLE_OK) {
strbuf_rtrim(&buffer);
if (buffer.len == 40)
ret = get_sha1_hex(buffer.buf, sha1);
else
ret = get_sha1_hex(buffer.buf, ref->old_sha1);
else if (!prefixcmp(buffer.buf, "ref: ")) {
ref->symref = xstrdup(buffer.buf + 5);
ret = 0;
} else
ret = 1;
} else {
ret = error("Couldn't get %s for %s\n%s",
url, ref, curl_errorstr);
url, ref->name, curl_errorstr);
}
} else {
ret = error("Unable to start request");

2
http.h
View File

@@ -105,6 +105,6 @@ static inline int missing__target(int code, int result)
#define missing_target(a) missing__target((a)->http_code, (a)->curl_result)
extern int http_fetch_ref(const char *base, const char *ref, unsigned char *sha1);
extern int http_fetch_ref(const char *base, struct ref *ref);
#endif /* HTTP_H */

View File

@@ -250,6 +250,9 @@ const char *git_author_info(int flag)
const char *git_committer_info(int flag)
{
if (getenv("GIT_COMMITTER_NAME") &&
getenv("GIT_COMMITTER_EMAIL"))
user_ident_explicitly_given = 1;
return fmt_ident(getenv("GIT_COMMITTER_NAME"),
getenv("GIT_COMMITTER_EMAIL"),
getenv("GIT_COMMITTER_DATE"),

View File

@@ -208,14 +208,13 @@ void log_write_email_headers(struct rev_info *opt, const char *name,
*extra_headers_p = extra_headers;
}
void show_log(struct rev_info *opt, const char *sep)
void show_log(struct rev_info *opt)
{
struct strbuf msgbuf;
struct log_info *log = opt->loginfo;
struct commit *commit = log->commit, *parent = log->parent;
int abbrev = opt->diffopt.abbrev;
int abbrev_commit = opt->abbrev_commit ? opt->abbrev : 40;
const char *extra;
const char *subject = NULL, *extra_headers = opt->extra_headers;
int need_8bit_cte = 0;
@@ -240,17 +239,10 @@ void show_log(struct rev_info *opt, const char *sep)
}
/*
* The "oneline" format has several special cases:
* - The pretty-printed commit lacks a newline at the end
* of the buffer, but we do want to make sure that we
* have a newline there. If the separator isn't already
* a newline, add an extra one.
* - unlike other log messages, the one-line format does
* not have an empty line between entries.
* If use_terminator is set, add a newline at the end of the entry.
* Otherwise, add a diffopt.line_termination character before all
* entries but the first. (IOW, as a separator between entries)
*/
extra = "";
if (*sep != '\n' && opt->use_terminator)
extra = "\n";
if (opt->shown_one && !opt->use_terminator)
putchar(opt->diffopt.line_termination);
opt->shown_one = 1;
@@ -292,10 +284,8 @@ void show_log(struct rev_info *opt, const char *sep)
show_reflog_message(opt->reflog_info,
opt->commit_format == CMIT_FMT_ONELINE,
opt->date_mode);
if (opt->commit_format == CMIT_FMT_ONELINE) {
printf("%s", sep);
if (opt->commit_format == CMIT_FMT_ONELINE)
return;
}
}
}
@@ -317,10 +307,10 @@ void show_log(struct rev_info *opt, const char *sep)
if (opt->show_log_size)
printf("log size %i\n", (int)msgbuf.len);
if (msgbuf.len) {
if (msgbuf.len)
fwrite(msgbuf.buf, sizeof(char), msgbuf.len, stdout);
printf("%s%s", extra, sep);
}
if (opt->use_terminator)
putchar('\n');
strbuf_release(&msgbuf);
}
@@ -342,7 +332,7 @@ int log_tree_diff_flush(struct rev_info *opt)
* an extra newline between the end of log and the
* output for readability.
*/
show_log(opt, opt->diffopt.msg_sep);
show_log(opt);
if ((opt->diffopt.output_format & ~DIFF_FORMAT_NO_OUTPUT) &&
opt->verbose_header &&
opt->commit_format != CMIT_FMT_ONELINE) {
@@ -430,7 +420,7 @@ int log_tree_commit(struct rev_info *opt, struct commit *commit)
shown = log_tree_diff(opt, commit, &log);
if (!shown && opt->loginfo && opt->always_show_header) {
log.parent = NULL;
show_log(opt, "");
show_log(opt);
shown = 1;
}
opt->loginfo = NULL;

View File

@@ -11,7 +11,7 @@ void init_log_tree_opt(struct rev_info *);
int log_tree_diff_flush(struct rev_info *);
int log_tree_commit(struct rev_info *, struct commit *);
int log_tree_opt_parse(struct rev_info *, const char **, int);
void show_log(struct rev_info *opt, const char *sep);
void show_log(struct rev_info *opt);
void show_decorations(struct commit *commit);
void log_write_email_headers(struct rev_info *opt, const char *name,
const char **subject_p,

119
name-hash.c Normal file
View File

@@ -0,0 +1,119 @@
/*
* name-hash.c
*
* Hashing names in the index state
*
* Copyright (C) 2008 Linus Torvalds
*/
#define NO_THE_INDEX_COMPATIBILITY_MACROS
#include "cache.h"
/*
* This removes bit 5 if bit 6 is set.
*
* That will make US-ASCII characters hash to their upper-case
* equivalent. We could easily do this one whole word at a time,
* but that's for future worries.
*/
static inline unsigned char icase_hash(unsigned char c)
{
return c & ~((c & 0x40) >> 1);
}
static unsigned int hash_name(const char *name, int namelen)
{
unsigned int hash = 0x123;
do {
unsigned char c = *name++;
c = icase_hash(c);
hash = hash*101 + c;
} while (--namelen);
return hash;
}
static void hash_index_entry(struct index_state *istate, struct cache_entry *ce)
{
void **pos;
unsigned int hash;
if (ce->ce_flags & CE_HASHED)
return;
ce->ce_flags |= CE_HASHED;
ce->next = NULL;
hash = hash_name(ce->name, ce_namelen(ce));
pos = insert_hash(hash, ce, &istate->name_hash);
if (pos) {
ce->next = *pos;
*pos = ce;
}
}
static void lazy_init_name_hash(struct index_state *istate)
{
int nr;
if (istate->name_hash_initialized)
return;
for (nr = 0; nr < istate->cache_nr; nr++)
hash_index_entry(istate, istate->cache[nr]);
istate->name_hash_initialized = 1;
}
void add_name_hash(struct index_state *istate, struct cache_entry *ce)
{
ce->ce_flags &= ~CE_UNHASHED;
if (istate->name_hash_initialized)
hash_index_entry(istate, ce);
}
static int slow_same_name(const char *name1, int len1, const char *name2, int len2)
{
if (len1 != len2)
return 0;
while (len1) {
unsigned char c1 = *name1++;
unsigned char c2 = *name2++;
len1--;
if (c1 != c2) {
c1 = toupper(c1);
c2 = toupper(c2);
if (c1 != c2)
return 0;
}
}
return 1;
}
static int same_name(const struct cache_entry *ce, const char *name, int namelen, int icase)
{
int len = ce_namelen(ce);
/*
* Always do exact compare, even if we want a case-ignoring comparison;
* we do the quick exact one first, because it will be the common case.
*/
if (len == namelen && !cache_name_compare(name, namelen, ce->name, len))
return 1;
return icase && slow_same_name(name, namelen, ce->name, len);
}
struct cache_entry *index_name_exists(struct index_state *istate, const char *name, int namelen, int icase)
{
unsigned int hash = hash_name(name, namelen);
struct cache_entry *ce;
lazy_init_name_hash(istate);
ce = lookup_hash(hash, &istate->name_hash);
while (ce) {
if (!(ce->ce_flags & CE_UNHASHED)) {
if (same_name(ce, name, namelen, icase))
return ce;
}
ce = ce->next;
}
return NULL;
}

View File

@@ -183,7 +183,6 @@ void fixup_pack_header_footer(int pack_fd,
char *index_pack_lockfile(int ip_out)
{
int len, s;
char packname[46];
/*
@@ -193,11 +192,8 @@ char *index_pack_lockfile(int ip_out)
* case, we need it to remove the corresponding .keep file
* later on. If we don't get that then tough luck with it.
*/
for (len = 0;
len < 46 && (s = xread(ip_out, packname+len, 46-len)) > 0;
len += s);
if (len == 46 && packname[45] == '\n' &&
memcmp(packname, "keep\t", 5) == 0) {
if (read_in_full(ip_out, packname, 46) == 46 && packname[45] == '\n' &&
memcmp(packname, "keep\t", 5) == 0) {
char path[PATH_MAX];
packname[45] = 0;
snprintf(path, sizeof(path), "%s/pack/pack-%s.keep",

View File

@@ -65,16 +65,11 @@ void packet_write(int fd, const char *fmt, ...)
static void safe_read(int fd, void *buffer, unsigned size)
{
size_t n = 0;
while (n < size) {
ssize_t ret = xread(fd, (char *) buffer + n, size - n);
if (ret < 0)
die("read error (%s)", strerror(errno));
if (!ret)
die("The remote end hung up unexpectedly");
n += ret;
}
ssize_t ret = read_in_full(fd, buffer, size);
if (ret < 0)
die("read error (%s)", strerror(errno));
else if (ret < size)
die("The remote end hung up unexpectedly");
}
int packet_read_line(int fd, char *buffer, unsigned size)

View File

@@ -23,80 +23,21 @@
struct index_state the_index;
static unsigned int hash_name(const char *name, int namelen)
{
unsigned int hash = 0x123;
do {
unsigned char c = *name++;
hash = hash*101 + c;
} while (--namelen);
return hash;
}
static void hash_index_entry(struct index_state *istate, struct cache_entry *ce)
{
void **pos;
unsigned int hash;
if (ce->ce_flags & CE_HASHED)
return;
ce->ce_flags |= CE_HASHED;
ce->next = NULL;
hash = hash_name(ce->name, ce_namelen(ce));
pos = insert_hash(hash, ce, &istate->name_hash);
if (pos) {
ce->next = *pos;
*pos = ce;
}
}
static void lazy_init_name_hash(struct index_state *istate)
{
int nr;
if (istate->name_hash_initialized)
return;
for (nr = 0; nr < istate->cache_nr; nr++)
hash_index_entry(istate, istate->cache[nr]);
istate->name_hash_initialized = 1;
}
static void set_index_entry(struct index_state *istate, int nr, struct cache_entry *ce)
{
ce->ce_flags &= ~CE_UNHASHED;
istate->cache[nr] = ce;
if (istate->name_hash_initialized)
hash_index_entry(istate, ce);
add_name_hash(istate, ce);
}
static void replace_index_entry(struct index_state *istate, int nr, struct cache_entry *ce)
{
struct cache_entry *old = istate->cache[nr];
remove_index_entry(old);
remove_name_hash(old);
set_index_entry(istate, nr, ce);
istate->cache_changed = 1;
}
int index_name_exists(struct index_state *istate, const char *name, int namelen)
{
unsigned int hash = hash_name(name, namelen);
struct cache_entry *ce;
lazy_init_name_hash(istate);
ce = lookup_hash(hash, &istate->name_hash);
while (ce) {
if (!(ce->ce_flags & CE_UNHASHED)) {
if (!cache_name_compare(name, namelen, ce->name, ce->ce_flags))
return 1;
}
ce = ce->next;
}
return 0;
}
/*
* This only updates the "non-critical" parts of the directory
* cache, ie the parts that aren't tracked by GIT, and only used
@@ -257,7 +198,8 @@ static int ce_match_stat_basic(struct cache_entry *ce, struct stat *st)
static int is_racy_timestamp(const struct index_state *istate, struct cache_entry *ce)
{
return (istate->timestamp &&
return (!S_ISGITLINK(ce->ce_mode) &&
istate->timestamp &&
((unsigned int)istate->timestamp) <= ce->ce_mtime);
}
@@ -438,7 +380,7 @@ int remove_index_entry_at(struct index_state *istate, int pos)
{
struct cache_entry *ce = istate->cache[pos];
remove_index_entry(ce);
remove_name_hash(ce);
istate->cache_changed = 1;
istate->cache_nr--;
if (pos >= istate->cache_nr)
@@ -488,21 +430,50 @@ static int index_name_pos_also_unmerged(struct index_state *istate,
return pos;
}
int add_file_to_index(struct index_state *istate, const char *path, int verbose)
static int different_name(struct cache_entry *ce, struct cache_entry *alias)
{
int size, namelen, pos;
struct stat st;
struct cache_entry *ce;
int len = ce_namelen(ce);
return ce_namelen(alias) != len || memcmp(ce->name, alias->name, len);
}
/*
* If we add a filename that aliases in the cache, we will use the
* name that we already have - but we don't want to update the same
* alias twice, because that implies that there were actually two
* different files with aliasing names!
*
* So we use the CE_ADDED flag to verify that the alias was an old
* one before we accept it as
*/
static struct cache_entry *create_alias_ce(struct cache_entry *ce, struct cache_entry *alias)
{
int len;
struct cache_entry *new;
if (alias->ce_flags & CE_ADDED)
die("Will not add file alias '%s' ('%s' already exists in index)", ce->name, alias->name);
/* Ok, create the new entry using the name of the existing alias */
len = ce_namelen(alias);
new = xcalloc(1, cache_entry_size(len));
memcpy(new->name, alias->name, len);
copy_cache_entry(new, ce);
free(ce);
return new;
}
int add_to_index(struct index_state *istate, const char *path, struct stat *st, int verbose)
{
int size, namelen;
mode_t st_mode = st->st_mode;
struct cache_entry *ce, *alias;
unsigned ce_option = CE_MATCH_IGNORE_VALID|CE_MATCH_RACY_IS_DIRTY;
if (lstat(path, &st))
die("%s: unable to stat (%s)", path, strerror(errno));
if (!S_ISREG(st.st_mode) && !S_ISLNK(st.st_mode) && !S_ISDIR(st.st_mode))
if (!S_ISREG(st_mode) && !S_ISLNK(st_mode) && !S_ISDIR(st_mode))
die("%s: can only add regular files, symbolic links or git-directories", path);
namelen = strlen(path);
if (S_ISDIR(st.st_mode)) {
if (S_ISDIR(st_mode)) {
while (namelen && path[namelen-1] == '/')
namelen--;
}
@@ -510,10 +481,10 @@ int add_file_to_index(struct index_state *istate, const char *path, int verbose)
ce = xcalloc(1, size);
memcpy(ce->name, path, namelen);
ce->ce_flags = namelen;
fill_stat_cache_info(ce, &st);
fill_stat_cache_info(ce, st);
if (trust_executable_bit && has_symlinks)
ce->ce_mode = create_ce_mode(st.st_mode);
ce->ce_mode = create_ce_mode(st_mode);
else {
/* If there is an existing entry, pick the mode bits and type
* from it, otherwise assume unexecutable regular file.
@@ -522,21 +493,22 @@ int add_file_to_index(struct index_state *istate, const char *path, int verbose)
int pos = index_name_pos_also_unmerged(istate, path, namelen);
ent = (0 <= pos) ? istate->cache[pos] : NULL;
ce->ce_mode = ce_mode_from_stat(ent, st.st_mode);
ce->ce_mode = ce_mode_from_stat(ent, st_mode);
}
pos = index_name_pos(istate, ce->name, namelen);
if (0 <= pos &&
!ce_stage(istate->cache[pos]) &&
!ie_match_stat(istate, istate->cache[pos], &st, ce_option)) {
alias = index_name_exists(istate, ce->name, ce_namelen(ce), ignore_case);
if (alias && !ce_stage(alias) && !ie_match_stat(istate, alias, st, ce_option)) {
/* Nothing changed, really */
free(ce);
ce_mark_uptodate(istate->cache[pos]);
ce_mark_uptodate(alias);
alias->ce_flags |= CE_ADDED;
return 0;
}
if (index_path(ce->sha1, path, &st, 1))
if (index_path(ce->sha1, path, st, 1))
die("unable to index file %s", path);
if (ignore_case && alias && different_name(ce, alias))
ce = create_alias_ce(ce, alias);
ce->ce_flags |= CE_ADDED;
if (add_index_entry(istate, ce, ADD_CACHE_OK_TO_ADD|ADD_CACHE_OK_TO_REPLACE))
die("unable to add %s to index",path);
if (verbose)
@@ -544,6 +516,14 @@ int add_file_to_index(struct index_state *istate, const char *path, int verbose)
return 0;
}
int add_file_to_index(struct index_state *istate, const char *path, int verbose)
{
struct stat st;
if (lstat(path, &st))
die("%s: unable to stat (%s)", path, strerror(errno));
return add_to_index(istate, path, &st, verbose);
}
struct cache_entry *make_cache_entry(unsigned int mode,
const unsigned char *sha1, const char *path, int stage,
int refresh)
@@ -1375,7 +1355,7 @@ int write_index(const struct index_state *istate, int newfd)
struct cache_entry *ce = cache[i];
if (ce->ce_flags & CE_REMOVE)
continue;
if (is_racy_timestamp(istate, ce))
if (!ce_uptodate(ce) && is_racy_timestamp(istate, ce))
ce_smudge_racily_clean_entry(ce);
if (ce_write_entry(&c, newfd, ce) < 0)
return -1;

15
refs.c
View File

@@ -352,6 +352,7 @@ int resolve_gitlink_ref(const char *path, const char *refname, unsigned char *re
{
int len = strlen(path), retval;
char *gitdir;
const char *tmp;
while (len && path[len-1] == '/')
len--;
@@ -359,9 +360,19 @@ int resolve_gitlink_ref(const char *path, const char *refname, unsigned char *re
return -1;
gitdir = xmalloc(len + MAXREFLEN + 8);
memcpy(gitdir, path, len);
memcpy(gitdir + len, "/.git/", 7);
memcpy(gitdir + len, "/.git", 6);
len += 5;
retval = resolve_gitlink_ref_recursive(gitdir, len+6, refname, result, 0);
tmp = read_gitfile_gently(gitdir);
if (tmp) {
free(gitdir);
len = strlen(tmp);
gitdir = xmalloc(len + MAXREFLEN + 3);
memcpy(gitdir, tmp, len);
}
gitdir[len] = '/';
gitdir[++len] = '\0';
retval = resolve_gitlink_ref_recursive(gitdir, len, refname, result, 0);
free(gitdir);
return retval;
}

View File

@@ -337,44 +337,49 @@ static int handle_config(const char *key, const char *value)
return 0;
}
remote = make_remote(name, subkey - name);
if (!value) {
/* if we ever have a boolean variable, e.g. "remote.*.disabled"
* [remote "frotz"]
* disabled
* is a valid way to set it to true; we get NULL in value so
* we need to handle it here.
*
* if (!strcmp(subkey, ".disabled")) {
* val = git_config_bool(key, value);
* return 0;
* } else
*
*/
return 0; /* ignore unknown booleans */
}
if (!strcmp(subkey, ".url")) {
add_url(remote, xstrdup(value));
if (!strcmp(subkey, ".mirror"))
remote->mirror = git_config_bool(key, value);
else if (!strcmp(subkey, ".skipdefaultupdate"))
remote->skip_default_update = git_config_bool(key, value);
else if (!strcmp(subkey, ".url")) {
const char *v;
if (git_config_string(&v, key, value))
return -1;
add_url(remote, v);
} else if (!strcmp(subkey, ".push")) {
add_push_refspec(remote, xstrdup(value));
const char *v;
if (git_config_string(&v, key, value))
return -1;
add_push_refspec(remote, v);
} else if (!strcmp(subkey, ".fetch")) {
add_fetch_refspec(remote, xstrdup(value));
const char *v;
if (git_config_string(&v, key, value))
return -1;
add_fetch_refspec(remote, v);
} else if (!strcmp(subkey, ".receivepack")) {
const char *v;
if (git_config_string(&v, key, value))
return -1;
if (!remote->receivepack)
remote->receivepack = xstrdup(value);
remote->receivepack = v;
else
error("more than one receivepack given, using the first");
} else if (!strcmp(subkey, ".uploadpack")) {
const char *v;
if (git_config_string(&v, key, value))
return -1;
if (!remote->uploadpack)
remote->uploadpack = xstrdup(value);
remote->uploadpack = v;
else
error("more than one uploadpack given, using the first");
} else if (!strcmp(subkey, ".tagopt")) {
if (!strcmp(value, "--no-tags"))
remote->fetch_tags = -1;
} else if (!strcmp(subkey, ".proxy")) {
remote->http_proxy = xstrdup(value);
} else if (!strcmp(subkey, ".skipdefaultupdate"))
remote->skip_default_update = 1;
return git_config_string((const char **)&remote->http_proxy,
key, value);
}
return 0;
}
@@ -686,6 +691,13 @@ struct ref *alloc_ref(unsigned namelen)
return ret;
}
struct ref *alloc_ref_from_str(const char* str)
{
struct ref *ret = alloc_ref(strlen(str) + 1);
strcpy(ret->name, str);
return ret;
}
static struct ref *copy_ref(const struct ref *ref)
{
struct ref *ret = xmalloc(sizeof(struct ref) + strlen(ref->name) + 1);
@@ -706,13 +718,22 @@ struct ref *copy_ref_list(const struct ref *ref)
return ret;
}
void free_ref(struct ref *ref)
{
if (!ref)
return;
free(ref->remote_status);
free(ref->symref);
free(ref);
}
void free_refs(struct ref *ref)
{
struct ref *next;
while (ref) {
next = ref->next;
free(ref->peer_ref);
free(ref);
free_ref(ref);
ref = next;
}
}
@@ -783,7 +804,6 @@ static struct ref *try_explicit_object_name(const char *name)
{
unsigned char sha1[20];
struct ref *ref;
int len;
if (!*name) {
ref = alloc_ref(20);
@@ -793,21 +813,14 @@ static struct ref *try_explicit_object_name(const char *name)
}
if (get_sha1(name, sha1))
return NULL;
len = strlen(name) + 1;
ref = alloc_ref(len);
memcpy(ref->name, name, len);
ref = alloc_ref_from_str(name);
hashcpy(ref->new_sha1, sha1);
return ref;
}
static struct ref *make_linked_ref(const char *name, struct ref ***tail)
{
struct ref *ret;
size_t len;
len = strlen(name) + 1;
ret = alloc_ref(len);
memcpy(ret->name, name, len);
struct ref *ret = alloc_ref_from_str(name);
tail_link_ref(ret, tail);
return ret;
}
@@ -1111,9 +1124,7 @@ static struct ref *get_local_ref(const char *name)
return NULL;
if (!prefixcmp(name, "refs/")) {
ret = alloc_ref(strlen(name) + 1);
strcpy(ret->name, name);
return ret;
return alloc_ref_from_str(name);
}
if (!prefixcmp(name, "heads/") ||
@@ -1172,3 +1183,15 @@ int get_fetch_map(const struct ref *remote_refs,
return 0;
}
int resolve_remote_symref(struct ref *ref, struct ref *list)
{
if (!ref->symref)
return 0;
for (; list; list = list->next)
if (!strcmp(ref->symref, list->name)) {
hashcpy(ref->old_sha1, list->old_sha1);
return 0;
}
return 1;
}

View File

@@ -26,6 +26,7 @@ struct remote {
*/
int fetch_tags;
int skip_default_update;
int mirror;
const char *receivepack;
const char *uploadpack;
@@ -53,6 +54,8 @@ struct refspec {
struct ref *alloc_ref(unsigned namelen);
struct ref *alloc_ref_from_str(const char* str);
struct ref *copy_ref_list(const struct ref *ref);
int check_ref_type(const struct ref *ref, int flags);
@@ -62,6 +65,8 @@ int check_ref_type(const struct ref *ref, int flags);
*/
void free_refs(struct ref *ref);
int resolve_remote_symref(struct ref *ref, struct ref *list);
/*
* Removes and frees any duplicate refs in the map.
*/

Some files were not shown because too many files have changed in this diff Show More