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

This commit is contained in:
Johannes Sixt
2008-03-16 20:31:03 +01:00
130 changed files with 5856 additions and 2945 deletions

View File

@@ -0,0 +1,53 @@
GIT v1.5.4.5 Release Notes
==========================
Fixes since v1.5.4.4
--------------------
* You couldn't specify a custom editor whose path contains a whitespace
via GIT_EDITOR (and core.editor).
* The subdirectory filter to "git filter-branch" mishandled a history
where the subdirectory becomes empty and then later becomes non-empty.
* "git shortlog" gave an empty line if the original commit message was
malformed (e.g. a botched import from foreign SCM). Now it finds the
first non-empty line and uses it for better information.
* When the user fails to give a revision parameter to "git svn", an error
from the Perl interpreter was issued because the script lacked proper
error checking.
* After "git rebase" stopped due to conflicts, if the user played with
"git reset" and friends, "git rebase --abort" failed to go back to the
correct commit.
* Additional work trees prepared with git-new-workdir (in contrib/) did
not share git-svn metadata directory .git/svn with the original.
* "git-merge-recursive" did not mark addition of the same path with
different filemodes correctly as a conflict.
* "gitweb" gave malformed URL when pathinfo stype paths are in use.
* "-n" stands for "--no-tags" again for "git fetch".
* "git format-patch" did not detect the need to add 8-bit MIME header
when the user used format.header configuration.
* "rev~" revision specifier used to mean "rev", which was inconsistent
with how "rev^" worked. Now "rev~" is the same as "rev~1" (hence it
also is the same as "rev^1"), and "rev~0" is the same as "rev^0"
(i.e. it has to be a commit).
* "git quiltimport" did not grok empty lines, lines in "file -pNNN"
format to specify the prefix levels and lines with trailing comments.
* "git rebase -m" triggered pre-commit verification, which made
"rebase --continue" impossible.
--
exec >/var/tmp/1
echo O=$(git describe maint)
O=v1.5.4.4-25-ga6f7728
git shortlog --no-merges $O..maint

View File

@@ -6,7 +6,16 @@ Updates since v1.5.4
(subsystems)
* Comes with git-gui 0.9.3
* Comes with git-gui 0.9.3.
(portability)
* We shouldn't ask for BSD group ownership semantics by setting g+s bit
on directories on older BSD systems that refuses chmod() by non root
users. BSD semantics is the default there anyway.
* Bunch of portability improvement patches coming from an effort to port
to Solaris has been applied.
(performance)
@@ -27,6 +36,9 @@ Updates since v1.5.4
(usability, bells and whistles)
* Bash completion script (in contrib) are aware of more commands and
options.
* You can be warned when core.autocrlf conversion is applied in
such a way that results in an irreversible conversion.
@@ -54,11 +66,6 @@ Updates since v1.5.4
used to tell "git-fetch" and "git-push" to use different URL than what
is given from the command line.
* "git push <somewhere> HEAD" and "git push <somewhere> +HEAD" works as
expected; they push the current branch (and only the current branch).
In addition, HEAD can be written as the value of "remote.<there>.push"
configuration variable.
* "git add -i" behaves better even before you make an initial commit.
* "git am" refused to run from a subdirectory without a good reason.
@@ -114,24 +121,46 @@ Updates since v1.5.4
* "git gc" learned --quiet option.
* "git gc" now automatically prunes unreachable objects that are two
weeks old or older.
* "git grep" now knows "--name-only" is a synonym for the "-l" option.
* "git help <alias>" now reports "'git <alias>' is alias to <what>",
instead of saying "No manual entry for git-<alias>".
* "git help" can use different backends to show manual pages and this can
be configured using "man.viewer" configuration.
* "gitk" does not restore window position from $HOME/.gitk anymore (it
still restores the size).
* "git log --grep=<what>" learned "--fixed-strings" option to look for
<what> without treating it as a regular expression.
* "git gui" learned an auto-spell checking.
* "git push <somewhere> HEAD" and "git push <somewhere> +HEAD" works as
expected; they push the current branch (and only the current branch).
In addition, HEAD can be written as the value of "remote.<there>.push"
configuration variable.
* When the configuration variable "pack.threads" is set to 0, "git
repack" auto detects the number of CPUs and uses that many threads.
* "git send-email" learned to prompt for passwords
interactively.
* "git send-email" learned an easier way to suppress CC
recipients.
* When the configuration variable "pack.threads" is set to 0, "git
repack" auto detects the number of CPUs and uses that many threads.
* "git stash" learned "pop" command, that applies the latest stash and
removes it from the stash, and "drop" command to discard the named
stash entry.
* "git submodule" learned a new subcommand "summary" to show the
symmetric difference between the HEAD version and the work tree version
of the submodule commits.
* Various "git cvsimport", "git cvsexportcommit", "git svn" and
"git p4" improvements.
@@ -146,6 +175,8 @@ Updates since v1.5.4
* "git checkout" is rewritten in C.
* "git remote" is rewritten in C.
* Two conflict hunks that are separated by a very short span of common
lines are now coalesced into one larger hunk, to make the result easier
to read.
@@ -153,6 +184,8 @@ Updates since v1.5.4
* Run-command API's use of file descriptors is documented clearer and
is more consistent now.
* diff output can be sent to FILE * that is different from stdout. This
will help reimplementing more things in C.
Fixes since v1.5.4
------------------
@@ -168,6 +201,6 @@ this release, unless otherwise noted.
---
exec >/var/tmp/1
O=v1.5.4.3-428-g6b48990
O=v1.5.4.4-620-gc817faa
echo O=`git describe refs/heads/master`
git shortlog --no-merges $O..refs/heads/master ^refs/heads/maint

View File

@@ -420,6 +420,11 @@ branch.<name>.rebase::
it unless you understand the implications (see linkgit:git-rebase[1]
for details).
browser.<tool>.cmd::
Specify the command to invoke the specified browser. The
specified command is evaluated in shell with the URLs passed
as arguments. (See linkgit:git-web--browse[1].)
browser.<tool>.path::
Override the path for the given tool that may be used to
browse HTML help (see '-w' option in linkgit:git-help[1]) or a
@@ -590,6 +595,10 @@ gc.packrefs::
at some stage, and setting this to `false` will continue to
prevent `git pack-refs` from being run from `git gc`.
gc.pruneexpire::
When `git gc` is run, it will call `prune --expire 2.weeks.ago`.
Override the grace period with this config variable.
gc.reflogexpire::
`git reflog expire` removes reflog entries older than
this time; defaults to 90 days.
@@ -748,6 +757,10 @@ log.showroot::
Tools like linkgit:git-log[1] or linkgit:git-whatchanged[1], which
normally hide the root commit will now show it. True by default.
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.
@@ -860,7 +873,7 @@ pack.indexVersion::
whenever the corresponding pack is larger than 2 GB. Otherwise
the default is 1.
pack.packSizeLimit:
pack.packSizeLimit::
The default maximum size of a pack. This setting only affects
packing to a file, i.e. the git:// protocol is unaffected. It
can be overridden by the `\--max-pack-size` option of

View File

@@ -207,16 +207,14 @@ patch::
and the working tree file and asks you if you want to stage
the change of each hunk. You can say:
y - add the change from that hunk to index
n - do not add the change from that hunk to index
a - add the change from that hunk and all the rest to index
d - do not the change from that hunk nor any of the rest to index
j - do not decide on this hunk now, and view the next
undecided hunk
J - do not decide on this hunk now, and view the next hunk
k - do not decide on this hunk now, and view the previous
undecided hunk
K - do not decide on this hunk now, and view the previous hunk
y - stage this hunk
n - do not stage this hunk
a - stage this and all the remaining hunks in the file
d - do not stage this hunk nor any of the remaining hunks in the file
j - leave this hunk undecided, see next undecided hunk
J - leave this hunk undecided, see next hunk
k - leave this hunk undecided, see previous undecided hunk
K - leave this hunk undecided, see previous hunk
s - split the current hunk into smaller hunks
? - print help
+

View File

@@ -8,7 +8,7 @@ git-gc - Cleanup unnecessary files and optimize the local repository
SYNOPSIS
--------
'git-gc' [--prune] [--aggressive] [--auto] [--quiet]
'git-gc' [--aggressive] [--auto] [--quiet]
DESCRIPTION
-----------
@@ -25,17 +25,6 @@ operating performance. Some git commands may automatically run
OPTIONS
-------
--prune::
Usually `git-gc` packs refs, expires old reflog entries,
packs loose objects,
and removes old 'rerere' records. Removal
of unreferenced loose objects is an unsafe operation
while other git operations are in progress, so it is not
done by default. Pass this option if you want it, and only
when you know nobody else is creating new objects in the
repository at the same time (e.g. never use this option
in a cron script).
--aggressive::
Usually 'git-gc' runs very quickly while providing good disk
space utilization and performance. This option will cause
@@ -104,6 +93,10 @@ the value, the more time is spent optimizing the delta compression. See
the documentation for the --window' option in linkgit:git-repack[1] for
more details. This defaults to 10.
The optional configuration variable 'gc.pruneExpire' controls how old
the unreferenced loose objects have to be before they are pruned. The
default is "2 weeks ago".
See Also
--------
linkgit:git-prune[1]

View File

@@ -33,17 +33,21 @@ OPTIONS
option supersedes any other option.
-i|--info::
Use the 'info' program to display the manual page, instead of
the 'man' program that is used by default.
Display manual page for the command in the 'info' format. The
'info' program will be used for that purpose.
-m|--man::
Use the 'man' program to display the manual page. This may be
used to override a value set in the 'help.format'
configuration variable.
Display manual page for the command in the 'man' format. This
option may be used to override a value set in the
'help.format' configuration variable.
+
By default the 'man' program will be used to display the manual page,
but the 'man.viewer' configuration variable may be used to choose
other display programs (see below).
-w|--web::
Use a web browser to display the HTML manual page, instead of
the 'man' program that is used by default.
Display manual page for the command in the 'web' (HTML)
format. A web browser will be used for that purpose.
+
The web browser can be specified using the configuration variable
'help.browser', or 'web.browser' if the former is not set. If none of
@@ -54,6 +58,9 @@ linkgit:git-web--browse[1] for more information about this.
CONFIGURATION VARIABLES
-----------------------
help.format
~~~~~~~~~~~
If no command line option is passed, the 'help.format' configuration
variable will be checked. The following values are supported for this
variable; they make 'git-help' behave as their corresponding command
@@ -61,15 +68,47 @@ line option:
* "man" corresponds to '-m|--man',
* "info" corresponds to '-i|--info',
* "web" or "html" correspond to '-w|--web',
* "web" or "html" correspond to '-w|--web'.
help.browser, web.browser and browser.<tool>.path
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The 'help.browser', 'web.browser' and 'browser.<tool>.path' will also
be checked if the 'web' format is chosen (either by command line
option or configuration variable). See '-w|--web' in the OPTIONS
section above and linkgit:git-web--browse[1].
Note that these configuration variables should probably be set using
the '--global' flag, for example like this:
man.viewer
~~~~~~~~~~
The 'man.viewer' config variable will be checked if the 'man' format
is chosen. Only 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.
Multiple values may be given to this 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.
Note about git config --global
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Note that all these configuration variables should probably be set
using the '--global' flag, for example like this:
------------------------------------------------
$ git config --global help.format web

View File

@@ -12,6 +12,7 @@ SYNOPSIS
'git-submodule' [--quiet] add [-b branch] [--] <repository> [<path>]
'git-submodule' [--quiet] status [--cached] [--] [<path>...]
'git-submodule' [--quiet] [init|update] [--] [<path>...]
'git-submodule' [--quiet] summary [--summary-limit <n>] [commit] [--] [<path>...]
COMMANDS
@@ -47,6 +48,11 @@ update::
checkout the commit specified in the index of the containing repository.
This will make the submodules HEAD be detached.
summary::
Show commit summary between the given commit (defaults to HEAD) and
working tree/index. For a submodule in question, a series of commits
in the submodule between the given super project commit and the
index or working tree (switched by --cached) are shown.
OPTIONS
-------
@@ -57,9 +63,16 @@ OPTIONS
Branch of repository to add as submodule.
--cached::
Display the SHA-1 stored in the index, not the SHA-1 of the currently
checked out submodule commit. This option is only valid for the
status command.
This option is only valid for status and summary commands. These
commands typically use the commit found in the submodule HEAD, but
with this option, the commit stored in the index is used instead.
-n, --summary-limit::
This option is only valid for the summary command.
Limit the summary size (number of commits shown in total).
Giving 0 will disable the summary; a negative number means unlimted
(the default). This limit only applies to modified submodules. The
size is always limited to 1 for added/deleted/typechanged submodules.
<path>::
Path to submodule(s). When specified this will restrict the command

View File

@@ -27,6 +27,8 @@ The following browsers (or commands) are currently supported:
* dillo
* open (this is the default under Mac OS X GUI)
Custom commands may also be specified.
OPTIONS
-------
-b BROWSER|--browser=BROWSER::
@@ -43,16 +45,35 @@ OPTIONS
CONFIGURATION VARIABLES
-----------------------
CONF.VAR (from -c option) and web.browser
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The web browser can be specified using a configuration variable passed
with the -c (or --config) command line option, or the 'web.browser'
configuration variable if the former is not used.
browser.<tool>.path
~~~~~~~~~~~~~~~~~~~
You can explicitly provide a full path to your preferred browser by
setting the configuration variable 'browser.<tool>.path'. For example,
you can configure the absolute path to firefox by setting
'browser.firefox.path'. Otherwise, 'git-web--browse' assumes the tool
is available in PATH.
browser.<tool>.cmd
~~~~~~~~~~~~~~~~~~
When the browser, specified by options or configuration variables, is
not among the supported ones, then the corresponding
'browser.<tool>.cmd' configuration variable will be looked up. If this
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 git config --global
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Note that these configuration variables should probably be set using
the '--global' flag, for example like this:

View File

@@ -1,5 +1,9 @@
<!-- callout.xsl: converts asciidoc callouts to man page format -->
<!-- Based on callouts.xsl. Fixes man page callouts for DocBook 1.72 XSL -->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:param name="man.output.quietly" select="1"/>
<xsl:param name="refentry.meta.get.quietly" select="1"/>
<xsl:template match="co">
<xsl:value-of select="concat('&#x2593;fB(',substring-after(@id,'-'),')&#x2593;fR')"/>
</xsl:template>

View File

@@ -148,6 +148,9 @@ all::
# is a simplified version of the merge sort used in glibc. This is
# recommended if Git triggers O(n^2) behavior in your platform's qsort().
#
# Define NO_EXTERNAL_GREP if you don't want "git grep" to ever call
# your external grep (e.g., if your system lacks grep, if its grep is
# broken, or spawning external process is slower than built-in grep git has).
GIT-VERSION-FILE: .FORCE-GIT-VERSION-FILE
@$(SHELL_PATH) ./GIT-VERSION-GEN
@@ -796,6 +799,9 @@ endif
ifdef DIR_HAS_BSD_GROUP_SEMANTICS
COMPAT_CFLAGS += -DDIR_HAS_BSD_GROUP_SEMANTICS
endif
ifdef NO_EXTERNAL_GREP
BASIC_CFLAGS += -DNO_EXTERNAL_GREP
endif
ifeq ($(TCLTK_PATH),)
NO_TCLTK=NoThanks
@@ -903,6 +909,7 @@ common-cmds.h: $(wildcard Documentation/git-*.txt)
$(patsubst %.sh,%,$(SCRIPT_SH)) : % : %.sh
$(QUIET_GEN)$(RM) $@ $@+ && \
sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \
-e 's|@SHELL_PATH@|$(SHELL_PATH_SQ)|' \
-e 's|@@PERL@@|$(PERL_PATH_SQ)|g' \
-e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \
-e 's/@@NO_CURL@@/$(NO_CURL)/g' \

View File

@@ -40,6 +40,8 @@ static struct option builtin_fetch_options[] = {
"force overwrite of local branch"),
OPT_SET_INT('t', "tags", &tags,
"fetch all tags and associated objects", TAGS_SET),
OPT_SET_INT('n', NULL, &tags,
"do not fetch all tags (--no-tags)", TAGS_UNSET),
OPT_BOOLEAN('k', "keep", &keep, "keep downloaded pack"),
OPT_BOOLEAN('u', "update-head-ok", &update_head_ok,
"allow updating of HEAD ref"),

View File

@@ -26,12 +26,13 @@ static int pack_refs = 1;
static int aggressive_window = -1;
static int gc_auto_threshold = 6700;
static int gc_auto_pack_limit = 20;
static char *prune_expire = "2.weeks.ago";
#define MAX_ADD 10
static const char *argv_pack_refs[] = {"pack-refs", "--all", "--prune", NULL};
static const char *argv_reflog[] = {"reflog", "expire", "--all", NULL};
static const char *argv_repack[MAX_ADD] = {"repack", "-d", "-l", NULL};
static const char *argv_prune[] = {"prune", NULL};
static const char *argv_prune[] = {"prune", "--expire", NULL, NULL};
static const char *argv_rerere[] = {"rerere", "gc", NULL};
static int gc_config(const char *var, const char *value)
@@ -55,6 +56,17 @@ static int gc_config(const char *var, const char *value)
gc_auto_pack_limit = git_config_int(var, value);
return 0;
}
if (!strcmp(var, "gc.pruneexpire")) {
if (!value)
return config_error_nonbool(var);
if (strcmp(value, "now")) {
unsigned long now = approxidate("now");
if (approxidate(value) >= now)
return error("Invalid %s: '%s'", var, value);
}
prune_expire = xstrdup(value);
return 0;
}
return git_default_config(var, value);
}
@@ -234,7 +246,8 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
if (run_command_v_opt(argv_repack, RUN_GIT_CMD))
return error(FAILED_RUN, argv_repack[0]);
if (prune && run_command_v_opt(argv_prune, RUN_GIT_CMD))
argv_prune[2] = prune_expire;
if (run_command_v_opt(argv_prune, RUN_GIT_CMD))
return error(FAILED_RUN, argv_prune[0]);
if (run_command_v_opt(argv_rerere, RUN_GIT_CMD))

View File

@@ -12,6 +12,14 @@
#include "builtin.h"
#include "grep.h"
#ifndef NO_EXTERNAL_GREP
#ifdef __unix__
#define NO_EXTERNAL_GREP 0
#else
#define NO_EXTERNAL_GREP 1
#endif
#endif
/*
* git grep pathspecs are somewhat different from diff-tree pathspecs;
* pathname wildcards are allowed.
@@ -153,7 +161,7 @@ static int grep_file(struct grep_opt *opt, const char *filename)
return i;
}
#ifdef __unix__
#if !NO_EXTERNAL_GREP
static int exec_grep(int argc, const char **argv)
{
pid_t pid;
@@ -372,7 +380,7 @@ static int grep_cache(struct grep_opt *opt, const char **paths, int cached)
int nr;
read_cache();
#ifdef __unix__
#if !NO_EXTERNAL_GREP
/*
* Use the external "grep" command for the case where
* we grep through the checked-out files. It tends to

View File

@@ -662,6 +662,7 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout,
int i;
const char *encoding = "utf-8";
struct diff_options opts;
int need_8bit_cte = 0;
if (rev->commit_format != CMIT_FMT_EMAIL)
die("Cover letter needs email format");
@@ -672,7 +673,8 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout,
head_sha1 = sha1_to_hex(head->object.sha1);
log_write_email_headers(rev, head_sha1, &subject_start, &extra_headers);
log_write_email_headers(rev, head_sha1, &subject_start, &extra_headers,
&need_8bit_cte);
committer = git_committer_info(0);
@@ -681,7 +683,7 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout,
pp_user_info(NULL, CMIT_FMT_EMAIL, &sb, committer, DATE_RFC2822,
encoding);
pp_title_line(CMIT_FMT_EMAIL, &msg, &sb, subject_start, extra_headers,
encoding, 0);
encoding, need_8bit_cte);
pp_remainder(CMIT_FMT_EMAIL, &msg, &sb, 0);
printf("%s\n", sb.buf);

View File

@@ -57,7 +57,8 @@ int cmd_merge_file(int argc, const char **argv, const char *prefix)
if (!f)
ret = error("Could not open %s for writing", filename);
else if (fwrite(result.ptr, result.size, 1, f) != 1)
else if (result.size &&
fwrite(result.ptr, result.size, 1, f) != 1)
ret = error("Could not write to %s", filename);
else if (fclose(f))
ret = error("Could not close %s", filename);

View File

@@ -668,9 +668,20 @@ static struct merge_file_info merge_file(struct diff_filespec *o,
if (!sha_eq(a->sha1, o->sha1) && !sha_eq(b->sha1, o->sha1))
result.merge = 1;
result.mode = a->mode == o->mode ? b->mode: a->mode;
/*
* Merge modes
*/
if (a->mode == b->mode || a->mode == o->mode)
result.mode = b->mode;
else {
result.mode = a->mode;
if (b->mode != o->mode) {
result.clean = 0;
result.merge = 1;
}
}
if (sha_eq(a->sha1, o->sha1))
if (sha_eq(a->sha1, b->sha1) || sha_eq(a->sha1, o->sha1))
hashcpy(result.sha, b->sha1);
else if (sha_eq(b->sha1, o->sha1))
hashcpy(result.sha, a->sha1);

View File

@@ -454,6 +454,7 @@ static void write_pack_file(void)
struct pack_header hdr;
int do_progress = progress >> pack_to_stdout;
uint32_t nr_remaining = nr_result;
time_t last_mtime = 0;
if (do_progress)
progress_state = start_progress("Writing objects", nr_result);
@@ -504,6 +505,7 @@ static void write_pack_file(void)
if (!pack_to_stdout) {
mode_t mode = umask(0);
struct stat st;
char *idx_tmp_name, tmpname[PATH_MAX];
umask(mode);
@@ -511,6 +513,7 @@ static void write_pack_file(void)
idx_tmp_name = write_idx_file(NULL, written_list,
nr_written, sha1);
snprintf(tmpname, sizeof(tmpname), "%s-%s.pack",
base_name, sha1_to_hex(sha1));
if (adjust_perm(pack_tmp_name, mode))
@@ -519,6 +522,28 @@ static void write_pack_file(void)
if (rename(pack_tmp_name, tmpname))
die("unable to rename temporary pack file: %s",
strerror(errno));
/*
* Packs are runtime accessed in their mtime
* order since newer packs are more likely to contain
* younger objects. So if we are creating multiple
* packs then we should modify the mtime of later ones
* to preserve this property.
*/
if (stat(tmpname, &st) < 0) {
warning("failed to stat %s: %s",
tmpname, strerror(errno));
} else if (!last_mtime) {
last_mtime = st.st_mtime;
} else {
struct utimbuf utb;
utb.actime = st.st_atime;
utb.modtime = --last_mtime;
if (utime(tmpname, &utb) < 0)
warning("failed utime() on %s: %s",
tmpname, strerror(errno));
}
snprintf(tmpname, sizeof(tmpname), "%s-%s.idx",
base_name, sha1_to_hex(sha1));
if (adjust_perm(idx_tmp_name, mode))
@@ -527,6 +552,7 @@ static void write_pack_file(void)
if (rename(idx_tmp_name, tmpname))
die("unable to rename temporary index file: %s",
strerror(errno));
free(idx_tmp_name);
free(pack_tmp_name);
puts(sha1_to_hex(sha1));

View File

@@ -13,16 +13,15 @@
#include "dir.h"
#include "builtin.h"
#define MAX_TREES 8
static int nr_trees;
static struct tree *trees[MAX_TREES];
static struct tree *trees[MAX_UNPACK_TREES];
static int list_tree(unsigned char *sha1)
{
struct tree *tree;
if (nr_trees >= MAX_TREES)
die("I cannot read more than %d trees", MAX_TREES);
if (nr_trees >= MAX_UNPACK_TREES)
die("I cannot read more than %d trees", MAX_UNPACK_TREES);
tree = parse_tree_indirect(sha1);
if (!tree)
return -1;
@@ -97,7 +96,7 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix)
{
int i, newfd, stage = 0;
unsigned char sha1[20];
struct tree_desc t[MAX_TREES];
struct tree_desc t[MAX_UNPACK_TREES];
struct unpack_trees_options opts;
memset(&opts, 0, sizeof(opts));

View File

@@ -229,7 +229,9 @@ int cmd_shortlog(int argc, const char **argv, const char *prefix)
{
struct shortlog log;
struct rev_info rev;
int nongit;
prefix = setup_git_directory_gently(&nongit);
shortlog_init(&log);
/* since -n is a shadowed rev argument, parse our args first */
@@ -259,7 +261,7 @@ int cmd_shortlog(int argc, const char **argv, const char *prefix)
die ("unrecognized argument: %s", argv[1]);
/* assume HEAD if from a tty */
if (!rev.pending.nr && isatty(0))
if (!nongit && !rev.pending.nr && isatty(0))
add_head_to_pending(&rev);
if (rev.pending.nr == 0) {
read_from_stdin(&log);

View File

@@ -70,7 +70,7 @@ extern void pretty_print_commit(enum cmit_fmt fmt, const struct commit*,
struct strbuf *,
int abbrev, const char *subject,
const char *after_subject, enum date_mode,
int non_ascii_present);
int need_8bit_cte);
void pp_user_info(const char *what, enum cmit_fmt fmt, struct strbuf *sb,
const char *line, enum date_mode dmode,
const char *encoding);
@@ -80,7 +80,7 @@ void pp_title_line(enum cmit_fmt fmt,
const char *subject,
const char *after_subject,
const char *encoding,
int plain_non_ascii);
int need_8bit_cte);
void pp_remainder(enum cmit_fmt fmt,
const char **msg_p,
struct strbuf *sb,

View File

@@ -46,4 +46,5 @@ NO_MKDTEMP=@NO_MKDTEMP@
NO_ICONV=@NO_ICONV@
OLD_ICONV=@OLD_ICONV@
NO_DEFLATE_BOUND=@NO_DEFLATE_BOUND@
FREAD_READS_DIRECTORIES=@FREAD_READS_DIRECTORIES@
SNPRINTF_RETURNS_BOGUS=@SNPRINTF_RETURNS_BOGUS@

View File

@@ -327,6 +327,26 @@ else
fi
AC_SUBST(NO_C99_FORMAT)
#
# Define FREAD_READS_DIRECTORIES if your are on a system which succeeds
# when attempting to read from an fopen'ed directory.
AC_CACHE_CHECK([whether system succeeds to read fopen'ed directory],
[ac_cv_fread_reads_directories],
[
AC_RUN_IFELSE(
[AC_LANG_PROGRAM([AC_INCLUDES_DEFAULT],
[[char c;
FILE *f = fopen(".", "r");
return f && fread(&c, 1, 1, f)]])],
[ac_cv_fread_reads_directories=no],
[ac_cv_fread_reads_directories=yes])
])
if test $ac_cv_fread_reads_directories = yes; then
FREAD_READS_DIRECTORIES=UnfortunatelyYes
else
FREAD_READS_DIRECTORIES=
fi
AC_SUBST(FREAD_READS_DIRECTORIES)
#
# Define SNPRINTF_RETURNS_BOGUS if your are on a system which snprintf()
# or vsnprintf() return -1 instead of number of characters which would
# have been written to the final string if enough space had been available.

284
contrib/examples/git-rerere.perl Executable file
View File

@@ -0,0 +1,284 @@
#!/usr/bin/perl
#
# REuse REcorded REsolve. This tool records a conflicted automerge
# result and its hand resolution, and helps to resolve future
# automerge that results in the same conflict.
#
# To enable this feature, create a directory 'rr-cache' under your
# .git/ directory.
use Digest;
use File::Path;
use File::Copy;
my $git_dir = $::ENV{GIT_DIR} || ".git";
my $rr_dir = "$git_dir/rr-cache";
my $merge_rr = "$git_dir/rr-cache/MERGE_RR";
my %merge_rr = ();
sub read_rr {
if (!-f $merge_rr) {
%merge_rr = ();
return;
}
my $in;
local $/ = "\0";
open $in, "<$merge_rr" or die "$!: $merge_rr";
while (<$in>) {
chomp;
my ($name, $path) = /^([0-9a-f]{40})\t(.*)$/s;
$merge_rr{$path} = $name;
}
close $in;
}
sub write_rr {
my $out;
open $out, ">$merge_rr" or die "$!: $merge_rr";
for my $path (sort keys %merge_rr) {
my $name = $merge_rr{$path};
print $out "$name\t$path\0";
}
close $out;
}
sub compute_conflict_name {
my ($path) = @_;
my @side = ();
my $in;
open $in, "<$path" or die "$!: $path";
my $sha1 = Digest->new("SHA-1");
my $hunk = 0;
while (<$in>) {
if (/^<<<<<<< .*/) {
$hunk++;
@side = ([], undef);
}
elsif (/^=======$/) {
$side[1] = [];
}
elsif (/^>>>>>>> .*/) {
my ($one, $two);
$one = join('', @{$side[0]});
$two = join('', @{$side[1]});
if ($two le $one) {
($one, $two) = ($two, $one);
}
$sha1->add($one);
$sha1->add("\0");
$sha1->add($two);
$sha1->add("\0");
@side = ();
}
elsif (@side == 0) {
next;
}
elsif (defined $side[1]) {
push @{$side[1]}, $_;
}
else {
push @{$side[0]}, $_;
}
}
close $in;
return ($sha1->hexdigest, $hunk);
}
sub record_preimage {
my ($path, $name) = @_;
my @side = ();
my ($in, $out);
open $in, "<$path" or die "$!: $path";
open $out, ">$name" or die "$!: $name";
while (<$in>) {
if (/^<<<<<<< .*/) {
@side = ([], undef);
}
elsif (/^=======$/) {
$side[1] = [];
}
elsif (/^>>>>>>> .*/) {
my ($one, $two);
$one = join('', @{$side[0]});
$two = join('', @{$side[1]});
if ($two le $one) {
($one, $two) = ($two, $one);
}
print $out "<<<<<<<\n";
print $out $one;
print $out "=======\n";
print $out $two;
print $out ">>>>>>>\n";
@side = ();
}
elsif (@side == 0) {
print $out $_;
}
elsif (defined $side[1]) {
push @{$side[1]}, $_;
}
else {
push @{$side[0]}, $_;
}
}
close $out;
close $in;
}
sub find_conflict {
my $in;
local $/ = "\0";
my $pid = open($in, '-|');
die "$!" unless defined $pid;
if (!$pid) {
exec(qw(git ls-files -z -u)) or die "$!: ls-files";
}
my %path = ();
my @path = ();
while (<$in>) {
chomp;
my ($mode, $sha1, $stage, $path) =
/^([0-7]+) ([0-9a-f]{40}) ([123])\t(.*)$/s;
$path{$path} |= (1 << $stage);
}
close $in;
while (my ($path, $status) = each %path) {
if ($status == 14) { push @path, $path; }
}
return @path;
}
sub merge {
my ($name, $path) = @_;
record_preimage($path, "$rr_dir/$name/thisimage");
unless (system('git', 'merge-file', map { "$rr_dir/$name/${_}image" }
qw(this pre post))) {
my $in;
open $in, "<$rr_dir/$name/thisimage" or
die "$!: $name/thisimage";
my $out;
open $out, ">$path" or die "$!: $path";
while (<$in>) { print $out $_; }
close $in;
close $out;
return 1;
}
return 0;
}
sub garbage_collect_rerere {
# We should allow specifying these from the command line and
# that is why the caller gives @ARGV to us, but I am lazy.
my $cutoff_noresolve = 15; # two weeks
my $cutoff_resolve = 60; # two months
my @to_remove;
while (<$rr_dir/*/preimage>) {
my ($dir) = /^(.*)\/preimage$/;
my $cutoff = ((-f "$dir/postimage")
? $cutoff_resolve
: $cutoff_noresolve);
my $age = -M "$_";
if ($cutoff <= $age) {
push @to_remove, $dir;
}
}
if (@to_remove) {
rmtree(\@to_remove);
}
}
-d "$rr_dir" || exit(0);
read_rr();
if (@ARGV) {
my $arg = shift @ARGV;
if ($arg eq 'clear') {
for my $path (keys %merge_rr) {
my $name = $merge_rr{$path};
if (-d "$rr_dir/$name" &&
! -f "$rr_dir/$name/postimage") {
rmtree(["$rr_dir/$name"]);
}
}
unlink $merge_rr;
}
elsif ($arg eq 'status') {
for my $path (keys %merge_rr) {
print $path, "\n";
}
}
elsif ($arg eq 'diff') {
for my $path (keys %merge_rr) {
my $name = $merge_rr{$path};
system('diff', ((@ARGV == 0) ? ('-u') : @ARGV),
'-L', "a/$path", '-L', "b/$path",
"$rr_dir/$name/preimage", $path);
}
}
elsif ($arg eq 'gc') {
garbage_collect_rerere(@ARGV);
}
else {
die "$0 unknown command: $arg\n";
}
exit 0;
}
my %conflict = map { $_ => 1 } find_conflict();
# MERGE_RR records paths with conflicts immediately after merge
# failed. Some of the conflicted paths might have been hand resolved
# in the working tree since then, but the initial run would catch all
# and register their preimages.
for my $path (keys %conflict) {
# This path has conflict. If it is not recorded yet,
# record the pre-image.
if (!exists $merge_rr{$path}) {
my ($name, $hunk) = compute_conflict_name($path);
next unless ($hunk);
$merge_rr{$path} = $name;
if (! -d "$rr_dir/$name") {
mkpath("$rr_dir/$name", 0, 0777);
print STDERR "Recorded preimage for '$path'\n";
record_preimage($path, "$rr_dir/$name/preimage");
}
}
}
# Now some of the paths that had conflicts earlier might have been
# hand resolved. Others may be similar to a conflict already that
# was resolved before.
for my $path (keys %merge_rr) {
my $name = $merge_rr{$path};
# We could resolve this automatically if we have images.
if (-f "$rr_dir/$name/preimage" &&
-f "$rr_dir/$name/postimage") {
if (merge($name, $path)) {
print STDERR "Resolved '$path' using previous resolution.\n";
# Then we do not have to worry about this path
# anymore.
delete $merge_rr{$path};
next;
}
}
# Let's see if we have resolved it.
(undef, my $hunk) = compute_conflict_name($path);
next if ($hunk);
print STDERR "Recorded resolution for '$path'.\n";
copy($path, "$rr_dir/$name/postimage");
# And we do not have to worry about this path anymore.
delete $merge_rr{$path};
}
# Write out the rest.
write_rr();

View File

@@ -63,7 +63,7 @@ mkdir -p "$new_workdir/.git" || die "unable to create \"$new_workdir\"!"
# create the links to the original repo. explictly exclude index, HEAD and
# logs/HEAD from the list since they are purely related to the current working
# directory, and should not be shared.
for x in config refs logs/refs objects info hooks packed-refs remotes rr-cache
for x in config refs logs/refs objects info hooks packed-refs remotes rr-cache svn
do
case $x in
*/*)

304
diff.c
View File

@@ -256,40 +256,41 @@ static int count_lines(const char *data, int size)
return count;
}
static void print_line_count(int count)
static void print_line_count(FILE *file, int count)
{
switch (count) {
case 0:
printf("0,0");
fprintf(file, "0,0");
break;
case 1:
printf("1");
fprintf(file, "1");
break;
default:
printf("1,%d", count);
fprintf(file, "1,%d", count);
break;
}
}
static void copy_file_with_prefix(int prefix, const char *data, int size,
static void copy_file_with_prefix(FILE *file,
int prefix, const char *data, int size,
const char *set, const char *reset)
{
int ch, nl_just_seen = 1;
while (0 < size--) {
ch = *data++;
if (nl_just_seen) {
fputs(set, stdout);
putchar(prefix);
fputs(set, file);
putc(prefix, file);
}
if (ch == '\n') {
nl_just_seen = 1;
fputs(reset, stdout);
fputs(reset, file);
} else
nl_just_seen = 0;
putchar(ch);
putc(ch, file);
}
if (!nl_just_seen)
printf("%s\n\\ No newline at end of file\n", reset);
fprintf(file, "%s\n\\ No newline at end of file\n", reset);
}
static void emit_rewrite_diff(const char *name_a,
@@ -322,17 +323,18 @@ static void emit_rewrite_diff(const char *name_a,
diff_populate_filespec(two, 0);
lc_a = count_lines(one->data, one->size);
lc_b = count_lines(two->data, two->size);
printf("%s--- %s%s%s\n%s+++ %s%s%s\n%s@@ -",
metainfo, a_name.buf, name_a_tab, reset,
metainfo, b_name.buf, name_b_tab, reset, fraginfo);
print_line_count(lc_a);
printf(" +");
print_line_count(lc_b);
printf(" @@%s\n", reset);
fprintf(o->file,
"%s--- %s%s%s\n%s+++ %s%s%s\n%s@@ -",
metainfo, a_name.buf, name_a_tab, reset,
metainfo, b_name.buf, name_b_tab, reset, fraginfo);
print_line_count(o->file, lc_a);
fprintf(o->file, " +");
print_line_count(o->file, lc_b);
fprintf(o->file, " @@%s\n", reset);
if (lc_a)
copy_file_with_prefix('-', one->data, one->size, old, reset);
copy_file_with_prefix(o->file, '-', one->data, one->size, old, reset);
if (lc_b)
copy_file_with_prefix('+', two->data, two->size, new, reset);
copy_file_with_prefix(o->file, '+', two->data, two->size, new, reset);
}
static int fill_mmfile(mmfile_t *mf, struct diff_filespec *one)
@@ -372,9 +374,10 @@ static void diff_words_append(char *line, unsigned long len,
struct diff_words_data {
struct xdiff_emit_state xm;
struct diff_words_buffer minus, plus;
FILE *file;
};
static void print_word(struct diff_words_buffer *buffer, int len, int color,
static void print_word(FILE *file, struct diff_words_buffer *buffer, int len, int color,
int suppress_newline)
{
const char *ptr;
@@ -391,15 +394,15 @@ static void print_word(struct diff_words_buffer *buffer, int len, int color,
len--;
}
fputs(diff_get_color(1, color), stdout);
fwrite(ptr, len, 1, stdout);
fputs(diff_get_color(1, DIFF_RESET), stdout);
fputs(diff_get_color(1, color), file);
fwrite(ptr, len, 1, file);
fputs(diff_get_color(1, DIFF_RESET), file);
if (eol) {
if (suppress_newline)
buffer->suppressed_newline = 1;
else
putchar('\n');
putc('\n', file);
}
}
@@ -409,20 +412,23 @@ static void fn_out_diff_words_aux(void *priv, char *line, unsigned long len)
if (diff_words->minus.suppressed_newline) {
if (line[0] != '+')
putchar('\n');
putc('\n', diff_words->file);
diff_words->minus.suppressed_newline = 0;
}
len--;
switch (line[0]) {
case '-':
print_word(&diff_words->minus, len, DIFF_FILE_OLD, 1);
print_word(diff_words->file,
&diff_words->minus, len, DIFF_FILE_OLD, 1);
break;
case '+':
print_word(&diff_words->plus, len, DIFF_FILE_NEW, 0);
print_word(diff_words->file,
&diff_words->plus, len, DIFF_FILE_NEW, 0);
break;
case ' ':
print_word(&diff_words->plus, len, DIFF_PLAIN, 0);
print_word(diff_words->file,
&diff_words->plus, len, DIFF_PLAIN, 0);
diff_words->minus.current += len;
break;
}
@@ -466,7 +472,7 @@ static void diff_words_show(struct diff_words_data *diff_words)
diff_words->minus.text.size = diff_words->plus.text.size = 0;
if (diff_words->minus.suppressed_newline) {
putchar('\n');
putc('\n', diff_words->file);
diff_words->minus.suppressed_newline = 0;
}
}
@@ -481,6 +487,7 @@ struct emit_callback {
const char **label_path;
struct diff_words_data *diff_words;
int *found_changesp;
FILE *file;
};
static void free_diff_words_data(struct emit_callback *ecbdata)
@@ -505,11 +512,11 @@ const char *diff_get_color(int diff_use_color, enum color_diff ix)
return "";
}
static void emit_line(const char *set, const char *reset, const char *line, int len)
static void emit_line(FILE *file, const char *set, const char *reset, const char *line, int len)
{
fputs(set, stdout);
fwrite(line, len, 1, stdout);
fputs(reset, stdout);
fputs(set, file);
fwrite(line, len, 1, file);
fputs(reset, file);
}
static void emit_add_line(const char *reset, struct emit_callback *ecbdata, const char *line, int len)
@@ -518,13 +525,13 @@ static void emit_add_line(const char *reset, struct emit_callback *ecbdata, cons
const char *set = diff_get_color(ecbdata->color_diff, DIFF_FILE_NEW);
if (!*ws)
emit_line(set, reset, line, len);
emit_line(ecbdata->file, set, reset, line, len);
else {
/* Emit just the prefix, then the rest. */
emit_line(set, reset, line, ecbdata->nparents);
emit_line(ecbdata->file, set, reset, line, ecbdata->nparents);
(void)check_and_emit_line(line + ecbdata->nparents,
len - ecbdata->nparents, ecbdata->ws_rule,
stdout, set, reset, ws);
ecbdata->file, set, reset, ws);
}
}
@@ -563,10 +570,10 @@ static void fn_out_consume(void *priv, char *line, unsigned long len)
name_a_tab = strchr(ecbdata->label_path[0], ' ') ? "\t" : "";
name_b_tab = strchr(ecbdata->label_path[1], ' ') ? "\t" : "";
printf("%s--- %s%s%s\n",
meta, ecbdata->label_path[0], reset, name_a_tab);
printf("%s+++ %s%s%s\n",
meta, ecbdata->label_path[1], reset, name_b_tab);
fprintf(ecbdata->file, "%s--- %s%s%s\n",
meta, ecbdata->label_path[0], reset, name_a_tab);
fprintf(ecbdata->file, "%s+++ %s%s%s\n",
meta, ecbdata->label_path[1], reset, name_b_tab);
ecbdata->label_path[0] = ecbdata->label_path[1] = NULL;
}
@@ -578,15 +585,16 @@ static void fn_out_consume(void *priv, char *line, unsigned long len)
if (2 <= i && i < len && line[i] == ' ') {
ecbdata->nparents = i - 1;
len = sane_truncate_line(ecbdata, line, len);
emit_line(diff_get_color(ecbdata->color_diff, DIFF_FRAGINFO),
emit_line(ecbdata->file,
diff_get_color(ecbdata->color_diff, DIFF_FRAGINFO),
reset, line, len);
if (line[len-1] != '\n')
putchar('\n');
putc('\n', ecbdata->file);
return;
}
if (len < ecbdata->nparents) {
emit_line(reset, reset, line, len);
emit_line(ecbdata->file, reset, reset, line, len);
return;
}
@@ -609,7 +617,7 @@ static void fn_out_consume(void *priv, char *line, unsigned long len)
diff_words_show(ecbdata->diff_words);
line++;
len--;
emit_line(plain, reset, line, len);
emit_line(ecbdata->file, plain, reset, line, len);
return;
}
for (i = 0; i < ecbdata->nparents && len; i++) {
@@ -620,7 +628,8 @@ static void fn_out_consume(void *priv, char *line, unsigned long len)
}
if (color != DIFF_FILE_NEW) {
emit_line(diff_get_color(ecbdata->color_diff, color),
emit_line(ecbdata->file,
diff_get_color(ecbdata->color_diff, color),
reset, line, len);
return;
}
@@ -759,20 +768,21 @@ static int scale_linear(int it, int width, int max_change)
return ((it - 1) * (width - 1) + max_change - 1) / (max_change - 1);
}
static void show_name(const char *prefix, const char *name, int len,
static void show_name(FILE *file,
const char *prefix, const char *name, int len,
const char *reset, const char *set)
{
printf(" %s%s%-*s%s |", set, prefix, len, name, reset);
fprintf(file, " %s%s%-*s%s |", set, prefix, len, name, reset);
}
static void show_graph(char ch, int cnt, const char *set, const char *reset)
static void show_graph(FILE *file, char ch, int cnt, const char *set, const char *reset)
{
if (cnt <= 0)
return;
printf("%s", set);
fprintf(file, "%s", set);
while (cnt--)
putchar(ch);
printf("%s", reset);
putc(ch, file);
fprintf(file, "%s", reset);
}
static void fill_print_name(struct diffstat_file *file)
@@ -877,18 +887,18 @@ static void show_stats(struct diffstat_t* data, struct diff_options *options)
}
if (data->files[i]->is_binary) {
show_name(prefix, name, len, reset, set);
printf(" Bin ");
printf("%s%d%s", del_c, deleted, reset);
printf(" -> ");
printf("%s%d%s", add_c, added, reset);
printf(" bytes");
printf("\n");
show_name(options->file, prefix, name, len, reset, set);
fprintf(options->file, " Bin ");
fprintf(options->file, "%s%d%s", del_c, deleted, reset);
fprintf(options->file, " -> ");
fprintf(options->file, "%s%d%s", add_c, added, reset);
fprintf(options->file, " bytes");
fprintf(options->file, "\n");
continue;
}
else if (data->files[i]->is_unmerged) {
show_name(prefix, name, len, reset, set);
printf(" Unmerged\n");
show_name(options->file, prefix, name, len, reset, set);
fprintf(options->file, " Unmerged\n");
continue;
}
else if (!data->files[i]->is_renamed &&
@@ -911,17 +921,18 @@ static void show_stats(struct diffstat_t* data, struct diff_options *options)
del = scale_linear(del, width, max_change);
total = add + del;
}
show_name(prefix, name, len, reset, set);
printf("%5d ", added + deleted);
show_graph('+', add, add_c, reset);
show_graph('-', del, del_c, reset);
putchar('\n');
show_name(options->file, prefix, name, len, reset, set);
fprintf(options->file, "%5d ", added + deleted);
show_graph(options->file, '+', add, add_c, reset);
show_graph(options->file, '-', del, del_c, reset);
fprintf(options->file, "\n");
}
printf("%s %d files changed, %d insertions(+), %d deletions(-)%s\n",
fprintf(options->file,
"%s %d files changed, %d insertions(+), %d deletions(-)%s\n",
set, total_files, adds, dels, reset);
}
static void show_shortstats(struct diffstat_t* data)
static void show_shortstats(struct diffstat_t* data, struct diff_options *options)
{
int i, adds = 0, dels = 0, total_files = data->nr;
@@ -942,7 +953,7 @@ static void show_shortstats(struct diffstat_t* data)
}
}
}
printf(" %d files changed, %d insertions(+), %d deletions(-)\n",
fprintf(options->file, " %d files changed, %d insertions(+), %d deletions(-)\n",
total_files, adds, dels);
}
@@ -957,24 +968,25 @@ static void show_numstat(struct diffstat_t* data, struct diff_options *options)
struct diffstat_file *file = data->files[i];
if (file->is_binary)
printf("-\t-\t");
fprintf(options->file, "-\t-\t");
else
printf("%d\t%d\t", file->added, file->deleted);
fprintf(options->file,
"%d\t%d\t", file->added, file->deleted);
if (options->line_termination) {
fill_print_name(file);
if (!file->is_renamed)
write_name_quoted(file->name, stdout,
write_name_quoted(file->name, options->file,
options->line_termination);
else {
fputs(file->print_name, stdout);
putchar(options->line_termination);
fputs(file->print_name, options->file);
putc(options->line_termination, options->file);
}
} else {
if (file->is_renamed) {
putchar('\0');
write_name_quoted(file->from_name, stdout, '\0');
putc('\0', options->file);
write_name_quoted(file->from_name, options->file, '\0');
}
write_name_quoted(file->name, stdout, '\0');
write_name_quoted(file->name, options->file, '\0');
}
}
}
@@ -984,7 +996,7 @@ struct diffstat_dir {
int nr, percent, cumulative;
};
static long gather_dirstat(struct diffstat_dir *dir, unsigned long changed, const char *base, int baselen)
static long gather_dirstat(FILE *file, struct diffstat_dir *dir, unsigned long changed, const char *base, int baselen)
{
unsigned long this_dir = 0;
unsigned int sources = 0;
@@ -1002,7 +1014,7 @@ static long gather_dirstat(struct diffstat_dir *dir, unsigned long changed, cons
slash = strchr(f->name + baselen, '/');
if (slash) {
int newbaselen = slash + 1 - f->name;
this = gather_dirstat(dir, changed, f->name, newbaselen);
this = gather_dirstat(file, dir, changed, f->name, newbaselen);
sources++;
} else {
if (f->is_unmerged || f->is_binary)
@@ -1027,7 +1039,7 @@ static long gather_dirstat(struct diffstat_dir *dir, unsigned long changed, cons
if (permille) {
int percent = permille / 10;
if (percent >= dir->percent) {
printf("%4d.%01d%% %.*s\n", percent, permille % 10, baselen, base);
fprintf(file, "%4d.%01d%% %.*s\n", percent, permille % 10, baselen, base);
if (!dir->cumulative)
return 0;
}
@@ -1060,7 +1072,7 @@ static void show_dirstat(struct diffstat_t *data, struct diff_options *options)
dir.nr = data->nr;
dir.percent = options->dirstat_percent;
dir.cumulative = options->output_format & DIFF_FORMAT_CUMULATIVE;
gather_dirstat(&dir, changed, "", 0);
gather_dirstat(options->file, &dir, changed, "", 0);
}
static void free_diffstat_info(struct diffstat_t *diffstat)
@@ -1083,6 +1095,7 @@ struct checkdiff_t {
int lineno, color_diff;
unsigned ws_rule;
unsigned status;
FILE *file;
};
static void checkdiff_consume(void *priv, char *line, unsigned long len)
@@ -1100,11 +1113,11 @@ static void checkdiff_consume(void *priv, char *line, unsigned long len)
if (!data->status)
return;
err = whitespace_error_string(data->status);
printf("%s:%d: %s.\n", data->filename, data->lineno, err);
fprintf(data->file, "%s:%d: %s.\n", data->filename, data->lineno, err);
free(err);
emit_line(set, reset, line, 1);
emit_line(data->file, set, reset, line, 1);
(void)check_and_emit_line(line + 1, len - 1, data->ws_rule,
stdout, set, reset, ws);
data->file, set, reset, ws);
} else if (line[0] == ' ')
data->lineno++;
else if (line[0] == '@') {
@@ -1140,7 +1153,7 @@ static unsigned char *deflate_it(char *data,
return deflated;
}
static void emit_binary_diff_body(mmfile_t *one, mmfile_t *two)
static void emit_binary_diff_body(FILE *file, mmfile_t *one, mmfile_t *two)
{
void *cp;
void *delta;
@@ -1169,13 +1182,13 @@ static void emit_binary_diff_body(mmfile_t *one, mmfile_t *two)
}
if (delta && delta_size < deflate_size) {
printf("delta %lu\n", orig_size);
fprintf(file, "delta %lu\n", orig_size);
free(deflated);
data = delta;
data_size = delta_size;
}
else {
printf("literal %lu\n", two->size);
fprintf(file, "literal %lu\n", two->size);
free(delta);
data = deflated;
data_size = deflate_size;
@@ -1193,17 +1206,18 @@ static void emit_binary_diff_body(mmfile_t *one, mmfile_t *two)
line[0] = bytes - 26 + 'a' - 1;
encode_85(line + 1, cp, bytes);
cp = (char *) cp + bytes;
puts(line);
fputs(line, file);
fputc('\n', file);
}
printf("\n");
fprintf(file, "\n");
free(data);
}
static void emit_binary_diff(mmfile_t *one, mmfile_t *two)
static void emit_binary_diff(FILE *file, mmfile_t *one, mmfile_t *two)
{
printf("GIT binary patch\n");
emit_binary_diff_body(one, two);
emit_binary_diff_body(two, one);
fprintf(file, "GIT binary patch\n");
emit_binary_diff_body(file, one, two);
emit_binary_diff_body(file, two, one);
}
static void setup_diff_attr_check(struct git_attr_check *check)
@@ -1334,25 +1348,25 @@ static void builtin_diff(const char *name_a,
b_two = quote_two(o->b_prefix, name_b + (*name_b == '/'));
lbl[0] = DIFF_FILE_VALID(one) ? a_one : "/dev/null";
lbl[1] = DIFF_FILE_VALID(two) ? b_two : "/dev/null";
printf("%sdiff --git %s %s%s\n", set, a_one, b_two, reset);
fprintf(o->file, "%sdiff --git %s %s%s\n", set, a_one, b_two, reset);
if (lbl[0][0] == '/') {
/* /dev/null */
printf("%snew file mode %06o%s\n", set, two->mode, reset);
fprintf(o->file, "%snew file mode %06o%s\n", set, two->mode, reset);
if (xfrm_msg && xfrm_msg[0])
printf("%s%s%s\n", set, xfrm_msg, reset);
fprintf(o->file, "%s%s%s\n", set, xfrm_msg, reset);
}
else if (lbl[1][0] == '/') {
printf("%sdeleted file mode %06o%s\n", set, one->mode, reset);
fprintf(o->file, "%sdeleted file mode %06o%s\n", set, one->mode, reset);
if (xfrm_msg && xfrm_msg[0])
printf("%s%s%s\n", set, xfrm_msg, reset);
fprintf(o->file, "%s%s%s\n", set, xfrm_msg, reset);
}
else {
if (one->mode != two->mode) {
printf("%sold mode %06o%s\n", set, one->mode, reset);
printf("%snew mode %06o%s\n", set, two->mode, reset);
fprintf(o->file, "%sold mode %06o%s\n", set, one->mode, reset);
fprintf(o->file, "%snew mode %06o%s\n", set, two->mode, reset);
}
if (xfrm_msg && xfrm_msg[0])
printf("%s%s%s\n", set, xfrm_msg, reset);
fprintf(o->file, "%s%s%s\n", set, xfrm_msg, reset);
/*
* we do not run diff between different kind
* of objects.
@@ -1376,10 +1390,10 @@ static void builtin_diff(const char *name_a,
!memcmp(mf1.ptr, mf2.ptr, mf1.size))
goto free_ab_and_return;
if (DIFF_OPT_TST(o, BINARY))
emit_binary_diff(&mf1, &mf2);
emit_binary_diff(o->file, &mf1, &mf2);
else
printf("Binary files %s and %s differ\n",
lbl[0], lbl[1]);
fprintf(o->file, "Binary files %s and %s differ\n",
lbl[0], lbl[1]);
o->found_changes = 1;
}
else {
@@ -1401,6 +1415,7 @@ static void builtin_diff(const char *name_a,
ecbdata.color_diff = DIFF_OPT_TST(o, COLOR_DIFF);
ecbdata.found_changesp = &o->found_changes;
ecbdata.ws_rule = whitespace_rule(name_b ? name_b : name_a);
ecbdata.file = o->file;
xpp.flags = XDF_NEED_MINIMAL | o->xdl_opts;
xecfg.ctxlen = o->context;
xecfg.flags = XDL_EMIT_FUNCNAMES;
@@ -1415,9 +1430,11 @@ static void builtin_diff(const char *name_a,
ecb.outf = xdiff_outf;
ecb.priv = &ecbdata;
ecbdata.xm.consume = fn_out_consume;
if (DIFF_OPT_TST(o, COLOR_DIFF_WORDS))
if (DIFF_OPT_TST(o, COLOR_DIFF_WORDS)) {
ecbdata.diff_words =
xcalloc(1, sizeof(struct diff_words_data));
ecbdata.diff_words->file = o->file;
}
xdi_diff(&mf1, &mf2, &xpp, &xecfg, &ecb);
if (DIFF_OPT_TST(o, COLOR_DIFF_WORDS))
free_diff_words_data(&ecbdata);
@@ -1496,6 +1513,7 @@ static void builtin_checkdiff(const char *name_a, const char *name_b,
data.lineno = 0;
data.color_diff = DIFF_OPT_TST(o, COLOR_DIFF);
data.ws_rule = whitespace_rule(attr_path);
data.file = o->file;
if (fill_mmfile(&mf1, one) < 0 || fill_mmfile(&mf2, two) < 0)
die("unable to read files to diff");
@@ -1966,7 +1984,7 @@ static void run_diff_cmd(const char *pgm,
builtin_diff(name, other ? other : name,
one, two, xfrm_msg, o, complete_rewrite);
else
printf("* Unmerged path %s\n", name);
fprintf(o->file, "* Unmerged path %s\n", name);
}
static void diff_fill_sha1_info(struct diff_filespec *one)
@@ -2157,6 +2175,9 @@ static void run_checkdiff(struct diff_filepair *p, struct diff_options *o)
void diff_setup(struct diff_options *options)
{
memset(options, 0, sizeof(*options));
options->file = stdout;
options->line_termination = '\n';
options->break_opt = -1;
options->rename_limit = -1;
@@ -2470,7 +2491,10 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac)
options->b_prefix = arg + 13;
else if (!strcmp(arg, "--no-prefix"))
options->a_prefix = options->b_prefix = "";
else
else if (!prefixcmp(arg, "--output=")) {
options->file = fopen(arg + strlen("--output="), "w");
options->close_file = 1;
} else
return 0;
return 1;
}
@@ -2599,15 +2623,15 @@ static void diff_flush_raw(struct diff_filepair *p, struct diff_options *opt)
int inter_name_termination = line_termination ? '\t' : '\0';
if (!(opt->output_format & DIFF_FORMAT_NAME_STATUS)) {
printf(":%06o %06o %s ", p->one->mode, p->two->mode,
diff_unique_abbrev(p->one->sha1, opt->abbrev));
printf("%s ", diff_unique_abbrev(p->two->sha1, opt->abbrev));
fprintf(opt->file, ":%06o %06o %s ", p->one->mode, p->two->mode,
diff_unique_abbrev(p->one->sha1, opt->abbrev));
fprintf(opt->file, "%s ", diff_unique_abbrev(p->two->sha1, opt->abbrev));
}
if (p->score) {
printf("%c%03d%c", p->status, similarity_index(p),
inter_name_termination);
fprintf(opt->file, "%c%03d%c", p->status, similarity_index(p),
inter_name_termination);
} else {
printf("%c%c", p->status, inter_name_termination);
fprintf(opt->file, "%c%c", p->status, inter_name_termination);
}
if (p->status == DIFF_STATUS_COPIED ||
@@ -2616,14 +2640,14 @@ static void diff_flush_raw(struct diff_filepair *p, struct diff_options *opt)
name_a = p->one->path;
name_b = p->two->path;
strip_prefix(opt->prefix_length, &name_a, &name_b);
write_name_quoted(name_a, stdout, inter_name_termination);
write_name_quoted(name_b, stdout, line_termination);
write_name_quoted(name_a, opt->file, inter_name_termination);
write_name_quoted(name_b, opt->file, line_termination);
} else {
const char *name_a, *name_b;
name_a = p->one->mode ? p->one->path : p->two->path;
name_b = NULL;
strip_prefix(opt->prefix_length, &name_a, &name_b);
write_name_quoted(name_a, stdout, line_termination);
write_name_quoted(name_a, opt->file, line_termination);
}
}
@@ -2825,62 +2849,62 @@ static void flush_one_pair(struct diff_filepair *p, struct diff_options *opt)
name_a = p->two->path;
name_b = NULL;
strip_prefix(opt->prefix_length, &name_a, &name_b);
write_name_quoted(name_a, stdout, opt->line_termination);
write_name_quoted(name_a, opt->file, opt->line_termination);
}
}
static void show_file_mode_name(const char *newdelete, struct diff_filespec *fs)
static void show_file_mode_name(FILE *file, const char *newdelete, struct diff_filespec *fs)
{
if (fs->mode)
printf(" %s mode %06o ", newdelete, fs->mode);
fprintf(file, " %s mode %06o ", newdelete, fs->mode);
else
printf(" %s ", newdelete);
write_name_quoted(fs->path, stdout, '\n');
fprintf(file, " %s ", newdelete);
write_name_quoted(fs->path, file, '\n');
}
static void show_mode_change(struct diff_filepair *p, int show_name)
static void show_mode_change(FILE *file, struct diff_filepair *p, int show_name)
{
if (p->one->mode && p->two->mode && p->one->mode != p->two->mode) {
printf(" mode change %06o => %06o%c", p->one->mode, p->two->mode,
fprintf(file, " mode change %06o => %06o%c", p->one->mode, p->two->mode,
show_name ? ' ' : '\n');
if (show_name) {
write_name_quoted(p->two->path, stdout, '\n');
write_name_quoted(p->two->path, file, '\n');
}
}
}
static void show_rename_copy(const char *renamecopy, struct diff_filepair *p)
static void show_rename_copy(FILE *file, const char *renamecopy, struct diff_filepair *p)
{
char *names = pprint_rename(p->one->path, p->two->path);
printf(" %s %s (%d%%)\n", renamecopy, names, similarity_index(p));
fprintf(file, " %s %s (%d%%)\n", renamecopy, names, similarity_index(p));
free(names);
show_mode_change(p, 0);
show_mode_change(file, p, 0);
}
static void diff_summary(struct diff_filepair *p)
static void diff_summary(FILE *file, struct diff_filepair *p)
{
switch(p->status) {
case DIFF_STATUS_DELETED:
show_file_mode_name("delete", p->one);
show_file_mode_name(file, "delete", p->one);
break;
case DIFF_STATUS_ADDED:
show_file_mode_name("create", p->two);
show_file_mode_name(file, "create", p->two);
break;
case DIFF_STATUS_COPIED:
show_rename_copy("copy", p);
show_rename_copy(file, "copy", p);
break;
case DIFF_STATUS_RENAMED:
show_rename_copy("rename", p);
show_rename_copy(file, "rename", p);
break;
default:
if (p->score) {
fputs(" rewrite ", stdout);
write_name_quoted(p->two->path, stdout, ' ');
printf("(%d%%)\n", similarity_index(p));
fputs(" rewrite ", file);
write_name_quoted(p->two->path, file, ' ');
fprintf(file, "(%d%%)\n", similarity_index(p));
}
show_mode_change(p, !p->score);
show_mode_change(file, p, !p->score);
break;
}
}
@@ -3088,14 +3112,14 @@ void diff_flush(struct diff_options *options)
if (output_format & DIFF_FORMAT_DIFFSTAT)
show_stats(&diffstat, options);
if (output_format & DIFF_FORMAT_SHORTSTAT)
show_shortstats(&diffstat);
show_shortstats(&diffstat, options);
free_diffstat_info(&diffstat);
separator++;
}
if (output_format & DIFF_FORMAT_SUMMARY && !is_summary_empty(q)) {
for (i = 0; i < q->nr; i++)
diff_summary(q->queue[i]);
diff_summary(options->file, q->queue[i]);
separator++;
}
@@ -3103,9 +3127,9 @@ void diff_flush(struct diff_options *options)
if (separator) {
if (options->stat_sep) {
/* attach patch instead of inline */
fputs(options->stat_sep, stdout);
fputs(options->stat_sep, options->file);
} else {
putchar(options->line_termination);
putc(options->line_termination, options->file);
}
}
@@ -3125,6 +3149,8 @@ free_queue:
free(q->queue);
q->queue = NULL;
q->nr = q->alloc = 0;
if (options->close_file)
fclose(options->file);
}
static void diffcore_apply_filter(const char *filter)

3
diff.h
View File

@@ -98,6 +98,9 @@ struct diff_options {
/* this is set by diffcore for DIFF_FORMAT_PATCH */
int found_changes;
FILE *file;
int close_file;
int nr_paths;
const char **paths;
int *pathlens;

View File

@@ -357,7 +357,7 @@ do
LAST_SIGNED_OFF_BY=`
sed -ne '/^Signed-off-by: /p' \
"$dotest/msg-clean" |
tail -n 1
sed -ne '$p'
`
ADD_SIGNOFF=`
test "$LAST_SIGNED_OFF_BY" = "$SIGNOFF" || {

View File

@@ -293,14 +293,14 @@ bisect_next() {
bisect_next_check good
skip=$(git for-each-ref --format='%(objectname)' \
"refs/bisect/skip-*" | tr '[\012]' ' ') || exit
"refs/bisect/skip-*" | tr '\012' ' ') || exit
BISECT_OPT=''
test -n "$skip" && BISECT_OPT='--bisect-all'
bad=$(git rev-parse --verify refs/bisect/bad) &&
good=$(git for-each-ref --format='^%(objectname)' \
"refs/bisect/good-*" | tr '[\012]' ' ') &&
"refs/bisect/good-*" | tr '\012' ' ') &&
eval="git rev-list --bisect-vars $BISECT_OPT $good $bad --" &&
eval="$eval $(cat "$GIT_DIR/BISECT_NAMES")" &&
eval=$(filter_skipped "$eval" "$skip") &&

View File

@@ -71,6 +71,7 @@
#include <sys/poll.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <utime.h>
#ifndef NO_SYS_SELECT_H
#include <sys/select.h>
#endif

View File

@@ -735,7 +735,7 @@ sub commit {
next unless $logmsg =~ $rx && $1;
my $mparent = $1 eq 'HEAD' ? $opt_o : $1;
if (my $sha1 = get_headref("$remote/$mparent")) {
push @commit_args, '-p', $mparent;
push @commit_args, '-p', "$remote/$mparent";
print "Merge parent branch: $mparent\n" if $opt_v;
}
}

View File

@@ -58,8 +58,8 @@ eval "$functions"
# "author" or "committer
set_ident () {
lid="$(echo "$1" | tr "A-Z" "a-z")"
uid="$(echo "$1" | tr "a-z" "A-Z")"
lid="$(echo "$1" | tr "[A-Z]" "[a-z]")"
uid="$(echo "$1" | tr "[a-z]" "[A-Z]")"
pick_id_script='
/^'$lid' /{
s/'\''/'\''\\'\'\''/g
@@ -281,7 +281,7 @@ while read commit parents; do
die "Could not checkout the index"
# files that $commit removed are now still in the working tree;
# remove them, else they would be added again
git ls-files -z --others | xargs -0 rm -f
git clean -q -f -x
eval "$filter_tree" < /dev/null ||
die "tree filter failed: $filter_tree"
@@ -309,7 +309,7 @@ while read commit parents; do
sed -e '1,/^$/d' <../commit | \
eval "$filter_msg" > ../message ||
die "msg filter failed: $filter_msg"
sh -c "$filter_commit" "git commit-tree" \
@SHELL_PATH@ -c "$filter_commit" "git commit-tree" \
$(git write-tree) $parentstr < ../message > ../map/$commit
done <../revs

View File

@@ -2089,7 +2089,7 @@ if {[is_enabled transport]} {
if {[is_MacOSX]} {
# -- Apple Menu (Mac OS X only)
#
.mbar add cascade -label [mc Apple] -menu .mbar.apple
.mbar add cascade -label Apple -menu .mbar.apple
menu .mbar.apple
.mbar.apple add command -label [mc "About %s" [appname]] \

View File

@@ -38,7 +38,7 @@ constructor pick {} {
menu $m_repo
if {[is_MacOSX]} {
$w.mbar add cascade -label [mc Apple] -menu .mbar.apple
$w.mbar add cascade -label Apple -menu .mbar.apple
menu $w.mbar.apple
$w.mbar.apple add command \
-label [mc "About %s" [appname]] \

View File

@@ -178,18 +178,6 @@ step.
$ msgmerge -U po/af.po po/git-gui.pot
[NEEDSWORK: who is responsible for updating po/git-gui.pot file by
running xgettext? IIRC, Christian recommended against running it
nilly-willy because it can become a source of unnecessary merge
conflicts. Perhaps we should mention something like "
The po/git-gui.pot file is updated by the internationalization
coordinator from time to time. You _could_ update it yourself, but
translators are discouraged from doing so because we would want all
language teams to be working off of the same version of git-gui.pot.
" here?]
This updates po/af.po (again, replace "af" with your language
code) so that it contains msgid lines (i.e. the original) that
your translation did not have before. There are a few things to
@@ -207,3 +195,53 @@ watch out for:
- New messages added to the software will have msgstr lines with empty
strings. You would need to translate them.
The po/git-gui.pot file is updated by the internationalization
coordinator from time to time. You _could_ update it yourself, but
translators are discouraged from doing so because we would want all
language teams to be working off of the same version of git-gui.pot.
****************************************************************
This section is a note to the internationalization coordinator, and
translators do not have to worry about it too much.
The message template file po/git-gui.pot needs to be kept up to date
relative to the software the translations apply to, and it is the
responsibility of the internationalization coordinator.
When updating po/git-gui.pot file, however, _never_ run "msgmerge -U
po/xx.po" for individual language translations, unless you are absolutely
sure that there is no outstanding work on translation for language xx.
Doing so will create unnecessary merge conflicts and force needless
re-translation on translators. The translator however may not have access
to the msgmerge tool, in which case the coordinator may run it for the
translator as a service.
But mistakes do happen. Suppose a translation was based on an older
version X, the POT file was updated at version Y and then msgmerge was run
at version Z for the language, and the translator sent in a patch based on
version X:
? translated
/
---X---Y---Z (master)
The coordinator could recover from such a mistake by first applying the
patch to X, replace the translated file in Z, and then running msgmerge
again based on the updated POT file and commit the result. The sequence
would look like this:
$ git checkout X
$ git am -s xx.patch
$ git checkout master
$ git checkout HEAD@{1} po/xx.po
$ msgmerge -U po/xx.po po/git-gui.pot
$ git commit -c HEAD@{1} po/xx.po
State in the message that the translated messages are based on a slightly
older version, and msgmerge was run to incorporate changes to message
templates from the updated POT file. The result needs to be further
translated, but at least the messages that were updated by the patch that
were not changed by the POT update will survive the process and do not
need to be re-translated.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -63,7 +63,23 @@ tmp_info="$tmp_dir/info"
commit=$(git rev-parse HEAD)
mkdir $tmp_dir || exit 2
for patch_name in $(grep -v '^#' < "$QUILT_PATCHES/series" ); do
while read patch_name level garbage
do
case "$patch_name" in ''|'#'*) continue;; esac
case "$level" in
-p*) ;;
''|'#'*)
level=;;
*)
echo "unable to parse patch level, ignoring it."
level=;;
esac
case "$garbage" in
''|'#'*);;
*)
echo "trailing garbage found in series file: $garbage"
exit 1;;
esac
if ! [ -f "$QUILT_PATCHES/$patch_name" ] ; then
echo "$patch_name doesn't exist. Skipping."
continue
@@ -113,10 +129,10 @@ for patch_name in $(grep -v '^#' < "$QUILT_PATCHES/series" ); do
fi
if [ -z "$dry_run" ] ; then
git apply --index -C1 "$tmp_patch" &&
git apply --index -C1 ${level:+"$level"} "$tmp_patch" &&
tree=$(git write-tree) &&
commit=$( (echo "$SUBJECT"; echo; cat "$tmp_msg") | git commit-tree $tree -p $commit) &&
git update-ref -m "quiltimport: $patch_name" HEAD $commit || exit 4
fi
done
done <"$QUILT_PATCHES/series"
rm -rf $tmp_dir || exit 5

View File

@@ -78,8 +78,8 @@ mark_action_done () {
sed -e 1q < "$TODO" >> "$DONE"
sed -e 1d < "$TODO" >> "$TODO".new
mv -f "$TODO".new "$TODO"
count=$(($(grep -ve '^$' -e '^#' < "$DONE" | wc -l)))
total=$(($count+$(grep -ve '^$' -e '^#' < "$TODO" | wc -l)))
count=$(grep -c '^[^#]' < "$DONE")
total=$(($count+$(grep -c '^[^#]' < "$TODO")))
if test "$last_count" != "$count"
then
last_count=$count
@@ -110,7 +110,7 @@ die_abort () {
}
has_action () {
grep -vqe '^$' -e '^#' "$1"
grep '^[^#]' "$1" >/dev/null
}
pick_one () {
@@ -218,7 +218,7 @@ nth_string () {
make_squash_message () {
if test -f "$SQUASH_MSG"; then
COUNT=$(($(sed -n "s/^# This is [^0-9]*\([1-9][0-9]*\).*/\1/p" \
< "$SQUASH_MSG" | tail -n 1)+1))
< "$SQUASH_MSG" | sed -ne '$p')+1))
echo "# This is a combination of $COUNT commits."
sed -e 1d -e '2,/^./{
/^$/d

View File

@@ -62,7 +62,7 @@ continue_merge () {
cmt=`cat "$dotest/current"`
if ! git diff-index --quiet HEAD --
then
if ! git-commit -C "$cmt"
if ! git commit --no-verify -C "$cmt"
then
echo "Commit failed, please do not call \"git commit\""
echo "directly, but instead do one of the following: "

View File

@@ -4,7 +4,9 @@
#
# Copyright (c) 2007 Lars Hjemli
USAGE='[--quiet] [--cached] [add <repo> [-b branch]|status|init|update] [--] [<path>...]'
USAGE="[--quiet] [--cached] \
[add <repo> [-b branch]|status|init|update|summary [-n|--summary-limit <n>] [<commit>]] \
[--] [<path>...]"
OPTIONS_SPEC=
. git-sh-setup
require_work_tree
@@ -230,7 +232,7 @@ cmd_init()
shift
done
git ls-files --stage -- "$@" | grep -e '^160000 ' |
git ls-files --stage -- "$@" | grep '^160000 ' |
while read mode sha1 stage path
do
# Skip already registered paths
@@ -284,7 +286,7 @@ cmd_update()
shift
done
git ls-files --stage -- "$@" | grep -e '^160000 ' |
git ls-files --stage -- "$@" | grep '^160000 ' |
while read mode sha1 stage path
do
name=$(module_name "$path") || exit
@@ -330,7 +332,175 @@ set_name_rev () {
) )
test -z "$revname" || revname=" ($revname)"
}
#
# Show commit summary for submodules in index or working tree
#
# If '--cached' is given, show summary between index and given commit,
# or between working tree and given commit
#
# $@ = [commit (default 'HEAD'),] requested paths (default all)
#
cmd_summary() {
summary_limit=-1
# parse $args after "submodule ... summary".
while test $# -ne 0
do
case "$1" in
--cached)
cached="$1"
;;
-n|--summary-limit)
if summary_limit=$(($2 + 0)) 2>/dev/null && test "$summary_limit" = "$2"
then
:
else
usage
fi
shift
;;
--)
shift
break
;;
-*)
usage
;;
*)
break
;;
esac
shift
done
test $summary_limit = 0 && return
if rev=$(git rev-parse --verify "$1^0" 2>/dev/null)
then
head=$rev
shift
else
head=HEAD
fi
cd_to_toplevel
# Get modified modules cared by user
modules=$(git diff-index $cached --raw $head -- "$@" |
grep -e '^:160000' -e '^:[0-7]* 160000' |
while read mod_src mod_dst sha1_src sha1_dst status name
do
# Always show modules deleted or type-changed (blob<->module)
test $status = D -o $status = T && echo "$name" && continue
# Also show added or modified modules which are checked out
GIT_DIR="$name/.git" git-rev-parse --git-dir >/dev/null 2>&1 &&
echo "$name"
done
)
test -n "$modules" &&
git diff-index $cached --raw $head -- $modules |
grep -e '^:160000' -e '^:[0-7]* 160000' |
cut -c2- |
while read mod_src mod_dst sha1_src sha1_dst status name
do
if test -z "$cached" &&
test $sha1_dst = 0000000000000000000000000000000000000000
then
case "$mod_dst" in
160000)
sha1_dst=$(GIT_DIR="$name/.git" git rev-parse HEAD)
;;
100644 | 100755 | 120000)
sha1_dst=$(git hash-object $name)
;;
000000)
;; # removed
*)
# unexpected type
echo >&2 "unexpected mode $mod_dst"
continue ;;
esac
fi
missing_src=
missing_dst=
test $mod_src = 160000 &&
! GIT_DIR="$name/.git" git-rev-parse --verify $sha1_src^0 >/dev/null 2>&1 &&
missing_src=t
test $mod_dst = 160000 &&
! GIT_DIR="$name/.git" git-rev-parse --verify $sha1_dst^0 >/dev/null 2>&1 &&
missing_dst=t
total_commits=
case "$missing_src,$missing_dst" in
t,)
errmsg=" Warn: $name doesn't contain commit $sha1_src"
;;
,t)
errmsg=" Warn: $name doesn't contain commit $sha1_dst"
;;
t,t)
errmsg=" Warn: $name doesn't contain commits $sha1_src and $sha1_dst"
;;
*)
errmsg=
total_commits=$(
if test $mod_src = 160000 -a $mod_dst = 160000
then
range="$sha1_src...$sha1_dst"
elif test $mod_src = 160000
then
range=$sha1_src
else
range=$sha1_dst
fi
GIT_DIR="$name/.git" \
git log --pretty=oneline --first-parent $range | wc -l
)
total_commits=" ($(($total_commits + 0)))"
;;
esac
sha1_abbr_src=$(echo $sha1_src | cut -c1-7)
sha1_abbr_dst=$(echo $sha1_dst | cut -c1-7)
if test $status = T
then
if test $mod_dst = 160000
then
echo "* $name $sha1_abbr_src(blob)->$sha1_abbr_dst(submodule)$total_commits:"
else
echo "* $name $sha1_abbr_src(submodule)->$sha1_abbr_dst(blob)$total_commits:"
fi
else
echo "* $name $sha1_abbr_src...$sha1_abbr_dst$total_commits:"
fi
if test -n "$errmsg"
then
# Don't give error msg for modification whose dst is not submodule
# i.e. deleted or changed to blob
test $mod_dst = 160000 && echo "$errmsg"
else
if test $mod_src = 160000 -a $mod_dst = 160000
then
limit=
test $summary_limit -gt 0 && limit="-$summary_limit"
GIT_DIR="$name/.git" \
git log $limit --pretty='format: %m %s' \
--first-parent $sha1_src...$sha1_dst
elif test $mod_dst = 160000
then
GIT_DIR="$name/.git" \
git log --pretty='format: > %s' -1 $sha1_dst
else
GIT_DIR="$name/.git" \
git log --pretty='format: < %s' -1 $sha1_src
fi
echo
fi
echo
done
}
#
# List all submodules, prefixed with:
# - submodule not initialized
@@ -367,7 +537,7 @@ cmd_status()
shift
done
git ls-files --stage -- "$@" | grep -e '^160000 ' |
git ls-files --stage -- "$@" | grep '^160000 ' |
while read mode sha1 stage path
do
name=$(module_name "$path") || exit
@@ -401,7 +571,7 @@ cmd_status()
while test $# != 0 && test -z "$command"
do
case "$1" in
add | init | update | status)
add | init | update | status | summary)
command=$1
;;
-q|--quiet)
@@ -416,7 +586,7 @@ do
branch="$2"; shift
;;
--cached)
cached=1
cached="$1"
;;
--)
break
@@ -440,8 +610,8 @@ then
usage
fi
# "--cached" is accepted only by "status"
if test -n "$cached" && test "$command" != status
# "--cached" is accepted only by "status" and "summary"
if test -n "$cached" && test "$command" != status -a "$command" != summary
then
usage
fi

View File

@@ -958,9 +958,10 @@ sub complete_url_ls_init {
"wanted to set to: $gs->{url}\n";
}
command_oneline('config', $k, $gs->{url}) unless $orig_url;
my $remote_path = "$ra->{svn_path}/$repo_path/*";
my $remote_path = "$ra->{svn_path}/$repo_path";
$remote_path =~ s#/+#/#g;
$remote_path =~ s#^/##g;
$remote_path .= "/*" if $remote_path !~ /\*/;
my ($n) = ($switch =~ /^--(\w+)/);
if (length $pfx && $pfx !~ m#/$#) {
die "--prefix='$pfx' must have a trailing slash '/'\n";

View File

@@ -23,12 +23,18 @@ USAGE='[--browser=browser|--tool=browser] [--config=conf.var] url/file ...'
NONGIT_OK=Yes
. git-sh-setup
valid_custom_tool()
{
browser_cmd="$(git config "browser.$1.cmd")"
test -n "$browser_cmd"
}
valid_tool() {
case "$1" in
firefox | iceweasel | konqueror | w3m | links | lynx | dillo | open)
;; # happy
*)
return 1
valid_custom_tool "$1" || return 1
;;
esac
}
@@ -122,7 +128,7 @@ else
init_browser_path "$browser"
if ! type "$browser_path" > /dev/null 2>&1; then
if test -z "$browser_cmd" && ! type "$browser_path" > /dev/null 2>&1; then
die "The browser $browser is not available as '$browser_path'."
fi
fi
@@ -157,4 +163,9 @@ case "$browser" in
dillo)
"$browser_path" "$@" &
;;
*)
if test -n "$browser_cmd"; then
( eval $browser_cmd "$@" )
fi
;;
esac

2
git.c
View File

@@ -343,7 +343,7 @@ static void handle_internal_command(int argc, const char **argv)
{ "revert", cmd_revert, RUN_SETUP | NEED_WORK_TREE },
{ "rm", cmd_rm, RUN_SETUP },
{ "send-pack", cmd_send_pack, RUN_SETUP },
{ "shortlog", cmd_shortlog, RUN_SETUP | USE_PAGER },
{ "shortlog", cmd_shortlog, USE_PAGER },
{ "show-branch", cmd_show_branch, RUN_SETUP },
{ "show", cmd_show, RUN_SETUP | USE_PAGER },
{ "status", cmd_status, RUN_SETUP | NEED_WORK_TREE },

View File

@@ -8,6 +8,7 @@ gitk_libdir ?= $(sharedir)/gitk/lib
msgsdir ?= $(gitk_libdir)/msgs
msgsdir_SQ = $(subst ','\'',$(msgsdir))
TCL_PATH ?= tclsh
TCLTK_PATH ?= wish
INSTALL ?= install
RM ?= rm -f
@@ -26,6 +27,9 @@ ifdef NO_MSGFMT
MSGFMT ?= $(TCL_PATH) po/po2msg.sh
else
MSGFMT ?= msgfmt
ifneq ($(shell $(MSGFMT) --tcl -l C -d . /dev/null 2>/dev/null; echo $$?),0)
MSGFMT := $(TCL_PATH) po/po2msg.sh
endif
endif
PO_TEMPLATE = po/gitk.pot

View File

@@ -82,7 +82,7 @@ proc dorunq {} {
proc start_rev_list {view} {
global startmsecs
global commfd leftover tclencoding datemode
global viewargs viewfiles commitidx viewcomplete vnextroot
global viewargs viewargscmd viewfiles commitidx viewcomplete vnextroot
global showlocalchanges commitinterest mainheadid
global progressdirn progresscoords proglastnc curview
@@ -90,13 +90,23 @@ proc start_rev_list {view} {
set commitidx($view) 0
set viewcomplete($view) 0
set vnextroot($view) 0
set args $viewargs($view)
if {$viewargscmd($view) ne {}} {
if {[catch {
set str [exec sh -c $viewargscmd($view)]
} err]} {
error_popup "Error executing --argscmd command: $err"
exit 1
}
set args [concat $args [split $str "\n"]]
}
set order "--topo-order"
if {$datemode} {
set order "--date-order"
}
if {[catch {
set fd [open [concat | git log --no-color -z --pretty=raw $order --parents \
--boundary $viewargs($view) "--" $viewfiles($view)] r]
--boundary $args "--" $viewfiles($view)] r]
} err]} {
error_popup "[mc "Error executing git rev-list:"] $err"
exit 1
@@ -393,6 +403,9 @@ proc readcommit {id} {
proc updatecommits {} {
global viewdata curview phase displayorder ordertok idpending
global children commitrow selectedline thickerline showneartags
global isworktree
set isworktree [expr {[exec git rev-parse --is-inside-work-tree] == "true"}]
if {$phase ne {}} {
stop_rev_list
@@ -827,6 +840,7 @@ proc makewindow {} {
}
frame .bleft.top
frame .bleft.mid
frame .bleft.bottom
button .bleft.top.search -text [mc "Search"] -command dosearch
pack .bleft.top.search -side left -padx 5
@@ -854,18 +868,25 @@ proc makewindow {} {
checkbutton .bleft.mid.ignspace -text [mc "Ignore space change"] \
-command changeignorespace -variable ignorespace
pack .bleft.mid.ignspace -side left -padx 5
set ctext .bleft.ctext
set ctext .bleft.bottom.ctext
text $ctext -background $bgcolor -foreground $fgcolor \
-state disabled -font textfont \
-yscrollcommand scrolltext -wrap none
-yscrollcommand scrolltext -wrap none \
-xscrollcommand ".bleft.bottom.sbhorizontal set"
if {$have_tk85} {
$ctext conf -tabstyle wordprocessor
}
scrollbar .bleft.sb -command "$ctext yview"
scrollbar .bleft.bottom.sb -command "$ctext yview"
scrollbar .bleft.bottom.sbhorizontal -command "$ctext xview" -orient h \
-width 10
pack .bleft.top -side top -fill x
pack .bleft.mid -side top -fill x
pack .bleft.sb -side right -fill y
pack $ctext -side left -fill both -expand 1
grid $ctext .bleft.bottom.sb -sticky nsew
grid .bleft.bottom.sbhorizontal -sticky ew
grid columnconfigure .bleft.bottom 0 -weight 1
grid rowconfigure .bleft.bottom 0 -weight 1
grid rowconfigure .bleft.bottom 1 -weight 0
pack .bleft.bottom -side top -fill both -expand 1
lappend bglist $ctext
lappend fglist $ctext
@@ -930,9 +951,17 @@ proc makewindow {} {
.pwbottom add .bright
.ctop add .pwbottom
# restore window position if known
# restore window width & height if known
if {[info exists geometry(main)]} {
wm geometry . "$geometry(main)"
if {[scan $geometry(main) "%dx%d" w h] >= 2} {
if {$w > [winfo screenwidth .]} {
set w [winfo screenwidth .]
}
if {$h > [winfo screenheight .]} {
set h [winfo screenheight .]
}
wm geometry . "${w}x$h"
}
}
if {[tk windowingsystem] eq {aqua}} {
@@ -1160,9 +1189,10 @@ proc savestuff {w} {
global canv canv2 canv3 mainfont textfont uifont tabstop
global stuffsaved findmergefiles maxgraphpct
global maxwidth showneartags showlocalchanges
global viewname viewfiles viewargs viewperm nextviewnum
global viewname viewfiles viewargs viewargscmd viewperm nextviewnum
global cmitmode wrapcomment datetimeformat limitdiffs
global colors bgcolor fgcolor diffcolors diffcontext selectbgcolor
global autoselect
if {$stuffsaved} return
if {![winfo viewable .]} return
@@ -1177,6 +1207,7 @@ proc savestuff {w} {
puts $f [list set maxwidth $maxwidth]
puts $f [list set cmitmode $cmitmode]
puts $f [list set wrapcomment $wrapcomment]
puts $f [list set autoselect $autoselect]
puts $f [list set showneartags $showneartags]
puts $f [list set showlocalchanges $showlocalchanges]
puts $f [list set datetimeformat $datetimeformat]
@@ -1199,7 +1230,7 @@ proc savestuff {w} {
puts -nonewline $f "set permviews {"
for {set v 0} {$v < $nextviewnum} {incr v} {
if {$viewperm($v)} {
puts $f "{[list $viewname($v) $viewfiles($v) $viewargs($v)]}"
puts $f "{[list $viewname($v) $viewfiles($v) $viewargs($v) $viewargscmd($v)]}"
}
}
puts $f "}"
@@ -1851,7 +1882,7 @@ proc shellsplit {str} {
proc newview {ishighlight} {
global nextviewnum newviewname newviewperm newishighlight
global newviewargs revtreeargs
global newviewargs revtreeargs viewargscmd newviewargscmd curview
set newishighlight $ishighlight
set top .gitkview
@@ -1859,16 +1890,17 @@ proc newview {ishighlight} {
raise $top
return
}
set newviewname($nextviewnum) "View $nextviewnum"
set newviewname($nextviewnum) "[mc "View"] $nextviewnum"
set newviewperm($nextviewnum) 0
set newviewargs($nextviewnum) [shellarglist $revtreeargs]
set newviewargscmd($nextviewnum) $viewargscmd($curview)
vieweditor $top $nextviewnum [mc "Gitk view definition"]
}
proc editview {} {
global curview
global viewname viewperm newviewname newviewperm
global viewargs newviewargs
global viewargs newviewargs viewargscmd newviewargscmd
set top .gitkvedit-$curview
if {[winfo exists $top]} {
@@ -1878,6 +1910,7 @@ proc editview {} {
set newviewname($curview) $viewname($curview)
set newviewperm($curview) $viewperm($curview)
set newviewargs($curview) [shellarglist $viewargs($curview)]
set newviewargscmd($curview) $viewargscmd($curview)
vieweditor $top $curview "Gitk: edit view $viewname($curview)"
}
@@ -1898,6 +1931,14 @@ proc vieweditor {top n title} {
entry $top.args -width 50 -textvariable newviewargs($n) \
-background $bgcolor
grid $top.args - -sticky ew -padx 5
message $top.ac -aspect 1000 \
-text [mc "Command to generate more commits to include:"]
grid $top.ac - -sticky w -pady 5
entry $top.argscmd -width 50 -textvariable newviewargscmd($n) \
-background white
grid $top.argscmd - -sticky ew -padx 5
message $top.l -aspect 1000 \
-text [mc "Enter files and directories to include, one per line:"]
grid $top.l - -sticky w
@@ -1941,7 +1982,7 @@ proc allviewmenus {n op args} {
proc newviewok {top n} {
global nextviewnum newviewperm newviewname newishighlight
global viewname viewfiles viewperm selectedview curview
global viewargs newviewargs viewhlmenu
global viewargs newviewargs viewargscmd newviewargscmd viewhlmenu
if {[catch {
set newargs [shellsplit $newviewargs($n)]
@@ -1965,6 +2006,7 @@ proc newviewok {top n} {
set viewperm($n) $newviewperm($n)
set viewfiles($n) $files
set viewargs($n) $newargs
set viewargscmd($n) $newviewargscmd($n)
addviewmenu $n
if {!$newishighlight} {
run showview $n
@@ -1981,9 +2023,11 @@ proc newviewok {top n} {
# doviewmenu $viewhlmenu 1 [list addvhighlight $n] \
# entryconf [list -label $viewname($n) -value $viewname($n)]
}
if {$files ne $viewfiles($n) || $newargs ne $viewargs($n)} {
if {$files ne $viewfiles($n) || $newargs ne $viewargs($n) || \
$newviewargscmd($n) ne $viewargscmd($n)} {
set viewfiles($n) $files
set viewargs($n) $newargs
set viewargscmd($n) $newviewargscmd($n)
if {$curview == $n} {
run updatecommits
}
@@ -2059,8 +2103,6 @@ proc showview {n} {
set ybot [expr {[lindex $span 1] * $ymax}]
if {$ytop < $y && $y < $ybot} {
set yscreen [expr {$y - $ytop}]
} else {
set yscreen [expr {($ybot - $ytop) / 2}]
}
} elseif {[info exists pending_select]} {
set selid $pending_select
@@ -2121,7 +2163,7 @@ proc showview {n} {
set yf 0
set row {}
set selectfirst 0
if {$selid ne {} && [info exists commitrow($n,$selid)]} {
if {[info exists yscreen] && [info exists commitrow($n,$selid)]} {
set row $commitrow($n,$selid)
# try to get the selected row in the same position on the screen
set ymax [lindex [$canv cget -scrollregion] 3]
@@ -2845,8 +2887,9 @@ proc dohidelocalchanges {} {
# spawn off a process to do git diff-index --cached HEAD
proc dodiffindex {} {
global localirow localfrow lserial showlocalchanges
global isworktree
if {!$showlocalchanges} return
if {!$showlocalchanges || !$isworktree} return
incr lserial
set localfrow -1
set localirow -1
@@ -4651,6 +4694,7 @@ proc selectline {l isnew} {
global commentend idtags linknum
global mergemax numcommits pending_select
global cmitmode showneartags allcommits
global autoselect
catch {unset pending_select}
$canv delete hover
@@ -4706,8 +4750,10 @@ proc selectline {l isnew} {
set currentid $id
$sha1entry delete 0 end
$sha1entry insert 0 $id
$sha1entry selection from 0
$sha1entry selection to end
if {$autoselect} {
$sha1entry selection from 0
$sha1entry selection to end
}
rhighlight_sel $id
$ctext conf -state normal
@@ -5605,7 +5651,7 @@ proc searchmarkvisible {doall} {
proc scrolltext {f0 f1} {
global searchstring
.bleft.sb set $f0 $f1
.bleft.bottom.sb set $f0 $f1
if {$searchstring ne {}} {
searchmarkvisible 0
}
@@ -7944,7 +7990,7 @@ proc doprefs {} {
global maxwidth maxgraphpct
global oldprefs prefstop showneartags showlocalchanges
global bgcolor fgcolor ctext diffcolors selectbgcolor
global tabstop limitdiffs
global tabstop limitdiffs autoselect
set top .gitkprefs
set prefstop $top
@@ -7974,6 +8020,11 @@ proc doprefs {} {
checkbutton $top.showlocal.b -variable showlocalchanges
pack $top.showlocal.b $top.showlocal.l -side left
grid x $top.showlocal -sticky w
frame $top.autoselect
label $top.autoselect.l -text [mc "Auto-select SHA1"] -font optionfont
checkbutton $top.autoselect.b -variable autoselect
pack $top.autoselect.b $top.autoselect.l -side left
grid x $top.autoselect -sticky w
label $top.ddisp -text [mc "Diff display options"]
grid $top.ddisp - -sticky w -pady 10
@@ -8464,6 +8515,7 @@ set maxlinelen 200
set showlocalchanges 1
set limitdiffs 1
set datetimeformat "%Y-%m-%d %H:%M:%S"
set autoselect 1
set colors {green red blue magenta darkgrey brown orange}
set bgcolor white
@@ -8523,8 +8575,9 @@ set mergeonly 0
set revtreeargs {}
set cmdline_files {}
set i 0
set revtreeargscmd {}
foreach arg $argv {
switch -- $arg {
switch -glob -- $arg {
"" { }
"-d" { set datemode 1 }
"--merge" {
@@ -8535,6 +8588,9 @@ foreach arg $argv {
set cmdline_files [lrange $argv [expr {$i + 1}] end]
break
}
"--argscmd=*" {
set revtreeargscmd [string range $arg 10 end]
}
default {
lappend revtreeargs $arg
}
@@ -8636,6 +8692,7 @@ set highlight_files {}
set viewfiles(0) {}
set viewperm(0) 0
set viewargs(0) {}
set viewargscmd(0) {}
set cmdlineok 0
set stopped 0
@@ -8644,6 +8701,7 @@ set patchnum 0
set localirow -1
set localfrow -1
set lserial 0
set isworktree [expr {[exec git rev-parse --is-inside-work-tree] == "true"}]
setcoords
makewindow
# wait for the window to become visible
@@ -8651,7 +8709,7 @@ tkwait visibility .
wm title . "[file tail $argv0]: [file tail [pwd]]"
readrefs
if {$cmdline_files ne {} || $revtreeargs ne {}} {
if {$cmdline_files ne {} || $revtreeargs ne {} || $revtreeargscmd ne {}} {
# create a view for the files/dirs specified on the command line
set curview 1
set selectedview 1
@@ -8659,6 +8717,7 @@ if {$cmdline_files ne {} || $revtreeargs ne {}} {
set viewname(1) [mc "Command line"]
set viewfiles(1) $cmdline_files
set viewargs(1) $revtreeargs
set viewargscmd(1) $revtreeargscmd
set viewperm(1) 0
addviewmenu 1
.bar.view entryconf [mc "Edit view..."] -state normal
@@ -8672,6 +8731,7 @@ if {[info exists permviews]} {
set viewname($n) [lindex $v 0]
set viewfiles($n) [lindex $v 1]
set viewargs($n) [lindex $v 2]
set viewargscmd($n) [lindex $v 3]
set viewperm($n) 1
addviewmenu $n
}

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

@@ -0,0 +1,890 @@
# Translation of gitk
# Copyright (C) 2005-2008 Paul Mackerras
# This file is distributed under the same license as the gitk package.
# Michele Ballabio <barra_cuda@katamail.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-13 17:34+0100\n"
"Last-Translator: Michele Ballabio <barra_cuda@katamail.com>\n"
"Language-Team: Italian\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 "Errore nell'esecuzione di git rev-list:"
#: gitk:124
msgid "Reading"
msgstr "Lettura in corso"
#: gitk:151 gitk:2191
msgid "Reading commits..."
msgstr "Lettura delle revisioni in corso..."
#: gitk:275
msgid "Can't parse git log output:"
msgstr "Impossibile elaborare i dati di git log:"
#: gitk:386 gitk:2195
msgid "No commits selected"
msgstr "Nessuna revisione selezionata"
#: gitk:500
msgid "No commit information available"
msgstr "Nessuna informazione disponibile sulle revisioni"
#: 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 "Annulla"
#: gitk:661
msgid "File"
msgstr "File"
#: gitk:663
msgid "Update"
msgstr "Aggiorna"
#: gitk:664
msgid "Reread references"
msgstr "Rileggi riferimenti"
#: gitk:665
msgid "List references"
msgstr "Elenca riferimenti"
#: gitk:666
msgid "Quit"
msgstr "Esci"
#: gitk:668
msgid "Edit"
msgstr "Modifica"
#: gitk:669
msgid "Preferences"
msgstr "Preferenze"
#: gitk:672 gitk:1892
msgid "View"
msgstr "Vista"
#: gitk:673
msgid "New view..."
msgstr "Nuova vista..."
#: gitk:674 gitk:2133 gitk:8722
msgid "Edit view..."
msgstr "Modifica vista..."
#: gitk:676 gitk:2134 gitk:8723
msgid "Delete view"
msgstr "Elimina vista"
#: gitk:678
msgid "All files"
msgstr "Tutti i file"
#: gitk:682
msgid "Help"
msgstr "Aiuto"
#: gitk:683 gitk:1317
msgid "About gitk"
msgstr "Informazioni su gitk"
#: gitk:684
msgid "Key bindings"
msgstr "Scorciatoie da tastiera"
#: gitk:741
msgid "SHA1 ID: "
msgstr "SHA1 ID: "
#: gitk:791
msgid "Find"
msgstr "Trova"
#: gitk:792
msgid "next"
msgstr "succ"
#: gitk:793
msgid "prev"
msgstr "prec"
#: gitk:794
msgid "commit"
msgstr "revisione"
#: gitk:797 gitk:799 gitk:2356 gitk:2379 gitk:2403 gitk:4306 gitk:4369
msgid "containing:"
msgstr "contenente:"
#: gitk:800 gitk:1778 gitk:1783 gitk:2431
msgid "touching paths:"
msgstr "che riguarda i percorsi:"
#: gitk:801 gitk:2436
msgid "adding/removing string:"
msgstr "che aggiunge/rimuove la stringa:"
#: gitk:810 gitk:812
msgid "Exact"
msgstr "Esatto"
#: gitk:812 gitk:2514 gitk:4274
msgid "IgnCase"
msgstr ""
#: gitk:812 gitk:2405 gitk:2512 gitk:4270
msgid "Regexp"
msgstr ""
#: gitk:814 gitk:815 gitk:2533 gitk:2563 gitk:2570 gitk:4380 gitk:4436
msgid "All fields"
msgstr "Tutti i campi"
#: gitk:815 gitk:2531 gitk:2563 gitk:4336
msgid "Headline"
msgstr "Titolo"
#: gitk:816 gitk:2531 gitk:4336 gitk:4436 gitk:4827
msgid "Comments"
msgstr "Commenti"
#: gitk:816 gitk:2531 gitk:2535 gitk:2570 gitk:4336 gitk:4763 gitk:5956
#: gitk:5971
msgid "Author"
msgstr "Autore"
#: gitk:816 gitk:2531 gitk:4336 gitk:4765
msgid "Committer"
msgstr "Revisione creata da"
#: gitk:845
msgid "Search"
msgstr "Cerca"
#: gitk:852
msgid "Diff"
msgstr ""
#: gitk:854
msgid "Old version"
msgstr "Vecchia versione"
#: gitk:856
msgid "New version"
msgstr "Nuova versione"
#: gitk:858
msgid "Lines of context"
msgstr "Linee di contesto"
#: gitk:868
msgid "Ignore space change"
msgstr "Ignora modifiche agli spazi"
#: gitk:926
msgid "Patch"
msgstr "Modifiche"
#: gitk:928
msgid "Tree"
msgstr "Directory"
#: gitk:1053 gitk:1068 gitk:6022
msgid "Diff this -> selected"
msgstr "Diff questo -> selezionato"
#: gitk:1055 gitk:1070 gitk:6023
msgid "Diff selected -> this"
msgstr "Diff selezionato -> questo"
#: gitk:1057 gitk:1072 gitk:6024
msgid "Make patch"
msgstr "Crea patch"
#: gitk:1058 gitk:6162
msgid "Create tag"
msgstr "Crea etichetta"
#: gitk:1059 gitk:6255
msgid "Write commit to file"
msgstr "Scrivi revisione in un file"
#: gitk:1060 gitk:6309
msgid "Create new branch"
msgstr "Crea un nuovo ramo"
#: gitk:1061
msgid "Cherry-pick this commit"
msgstr "Porta questa revisione in cima al ramo attuale"
#: gitk:1063
msgid "Reset HEAD branch to here"
msgstr "Aggiorna il ramo HEAD a questa revisione"
#: gitk:1079
msgid "Check out this branch"
msgstr "Attiva questo ramo"
#: gitk:1081
msgid "Remove this branch"
msgstr "Elimina questo ramo"
#: gitk:1087
msgid "Highlight this too"
msgstr "Evidenzia anche questo"
#: gitk:1089
msgid "Highlight this only"
msgstr "Evidenzia solo questo"
#: 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 visualizzatore di revisioni per git\n"
"\n"
"Copyright © 2005-2006 Paul Mackerras\n"
"\n"
"Utilizzo e redistribuzione permessi sotto i termini della GNU General Public "
"License"
#: gitk:1326 gitk:1387 gitk:6581
msgid "Close"
msgstr "Chiudi"
#: gitk:1345
msgid "Gitk key bindings"
msgstr "Scorciatoie da tastiera di Gitk"
#: gitk:1347
msgid "Gitk key bindings:"
msgstr "Scorciatoie da tastiera di Gitk:"
#: gitk:1349
#, tcl-format
msgid "<%s-Q>\t\tQuit"
msgstr "<%s-Q>\t\tEsci"
#: gitk:1350
msgid "<Home>\t\tMove to first commit"
msgstr "<Home>\t\tVai alla prima revisione"
#: gitk:1351
msgid "<End>\t\tMove to last commit"
msgstr "<End>\t\tVai all'ultima revisione"
#: gitk:1352
msgid "<Up>, p, i\tMove up one commit"
msgstr "<Up>, p, i\tVai più in alto di una revisione"
#: gitk:1353
msgid "<Down>, n, k\tMove down one commit"
msgstr "<Down>, n, k\tVai più in basso di una revisione"
#: gitk:1354
msgid "<Left>, z, j\tGo back in history list"
msgstr "<Left>, z, j\tTorna indietro nella cronologia"
#: gitk:1355
msgid "<Right>, x, l\tGo forward in history list"
msgstr "<Right>, x, l\tVai avanti nella cronologia"
#: gitk:1356
msgid "<PageUp>\tMove up one page in commit list"
msgstr "<PageUp>\tVai più in alto di una pagina nella lista delle revisioni"
#: gitk:1357
msgid "<PageDown>\tMove down one page in commit list"
msgstr "<PageDown>\tVai più in basso di una pagina nella lista delle revisioni"
#: gitk:1358
#, tcl-format
msgid "<%s-Home>\tScroll to top of commit list"
msgstr "<%s-Home>\tScorri alla cima della lista delle revisioni"
#: gitk:1359
#, tcl-format
msgid "<%s-End>\tScroll to bottom of commit list"
msgstr "<%s-End>\tScorri alla fine della lista delle revisioni"
#: gitk:1360
#, tcl-format
msgid "<%s-Up>\tScroll commit list up one line"
msgstr "<%s-Up>\tScorri la lista delle revisioni in alto di una riga"
#: gitk:1361
#, tcl-format
msgid "<%s-Down>\tScroll commit list down one line"
msgstr "<%s-Down>\tScorri la lista delle revisioni in basso di una riga"
#: gitk:1362
#, tcl-format
msgid "<%s-PageUp>\tScroll commit list up one page"
msgstr "<%s-PageUp>\tScorri la lista delle revisioni in alto di una pagina"
#: gitk:1363
#, tcl-format
msgid "<%s-PageDown>\tScroll commit list down one page"
msgstr "<%s-PageDown>\tScorri la lista delle revisioni in basso di una pagina"
#: gitk:1364
msgid "<Shift-Up>\tFind backwards (upwards, later commits)"
msgstr "<Shift-Up>\tTrova all'indietro (verso l'alto, revisioni successive)"
#: gitk:1365
msgid "<Shift-Down>\tFind forwards (downwards, earlier commits)"
msgstr "<Shift-Down>\tTrova in avanti (verso il basso, revisioni precedenti)"
#: gitk:1366
msgid "<Delete>, b\tScroll diff view up one page"
msgstr "<Delete>, b\tScorri la vista delle differenze in alto di una pagina"
#: gitk:1367
msgid "<Backspace>\tScroll diff view up one page"
msgstr "<Backspace>\tScorri la vista delle differenze in alto di una pagina"
#: gitk:1368
msgid "<Space>\t\tScroll diff view down one page"
msgstr "<Space>\t\tScorri la vista delle differenze in basso di una pagina"
#: gitk:1369
msgid "u\t\tScroll diff view up 18 lines"
msgstr "u\t\tScorri la vista delle differenze in alto di 18 linee"
#: gitk:1370
msgid "d\t\tScroll diff view down 18 lines"
msgstr "d\t\tScorri la vista delle differenze in basso di 18 linee"
#: gitk:1371
#, tcl-format
msgid "<%s-F>\t\tFind"
msgstr "<%s-F>\t\tTrova"
#: gitk:1372
#, tcl-format
msgid "<%s-G>\t\tMove to next find hit"
msgstr "<%s-G>\t\tTrova in avanti"
#: gitk:1373
msgid "<Return>\tMove to next find hit"
msgstr "<Return>\tTrova in avanti"
#: gitk:1374
msgid "/\t\tMove to next find hit, or redo find"
msgstr "/\t\tTrova in avanti, o cerca di nuovo"
#: gitk:1375
msgid "?\t\tMove to previous find hit"
msgstr "?\t\tTrova all'indietro"
#: gitk:1376
msgid "f\t\tScroll diff view to next file"
msgstr "f\t\tScorri la vista delle differenze al file successivo"
#: gitk:1377
#, tcl-format
msgid "<%s-S>\t\tSearch for next hit in diff view"
msgstr "<%s-S>\t\tCerca in avanti nella vista delle differenze"
#: gitk:1378
#, tcl-format
msgid "<%s-R>\t\tSearch for previous hit in diff view"
msgstr "<%s-R>\t\tCerca all'indietro nella vista delle differenze"
#: gitk:1379
#, tcl-format
msgid "<%s-KP+>\tIncrease font size"
msgstr "<%s-KP+>\tAumenta grandezza carattere"
#: gitk:1380
#, tcl-format
msgid "<%s-plus>\tIncrease font size"
msgstr "<%s-plus>\tAumenta grandezza carattere"
#: gitk:1381
#, tcl-format
msgid "<%s-KP->\tDecrease font size"
msgstr "<%s-KP->\tDiminuisci grandezza carattere"
#: gitk:1382
#, tcl-format
msgid "<%s-minus>\tDecrease font size"
msgstr "<%s-minus>\tDiminuisci grandezza carattere"
#: gitk:1383
msgid "<F5>\t\tUpdate"
msgstr "<F5>\t\tAggiorna"
#: gitk:1896
msgid "Gitk view definition"
msgstr "Scelta vista Gitk"
#: gitk:1921
msgid "Name"
msgstr "Nome"
#: gitk:1924
msgid "Remember this view"
msgstr "Ricorda questa vista"
#: gitk:1928
msgid "Commits to include (arguments to git rev-list):"
msgstr "Revisioni da includere (argomenti di git rev-list):"
#: gitk:1935
msgid "Command to generate more commits to include:"
msgstr "Comando che genera altre revisioni da visualizzare:"
#: gitk:1942
msgid "Enter files and directories to include, one per line:"
msgstr "Inserire file e directory da includere, uno per riga:"
#: gitk:1989
msgid "Error in commit selection arguments:"
msgstr "Errore negli argomenti di selezione delle revisioni:"
#: gitk:2043 gitk:2127 gitk:2583 gitk:2597 gitk:3781 gitk:8688 gitk:8689
msgid "None"
msgstr "Nessuno"
#: gitk:2531 gitk:4336 gitk:5958 gitk:5973
msgid "Date"
msgstr "Data"
#: gitk:2531 gitk:4336
msgid "CDate"
msgstr ""
#: gitk:2680 gitk:2685
msgid "Descendant"
msgstr "Discendente"
#: gitk:2681
msgid "Not descendant"
msgstr "Non discendente"
#: gitk:2688 gitk:2693
msgid "Ancestor"
msgstr "Ascendente"
#: gitk:2689
msgid "Not ancestor"
msgstr "Non ascendente"
#: gitk:2924
msgid "Local changes checked in to index but not committed"
msgstr "Modifiche locali presenti nell'indice ma non nell'archivio"
#: gitk:2954
msgid "Local uncommitted changes, not checked in to index"
msgstr "Modifiche locali non presenti né nell'archivio né nell'indice"
#: gitk:4305
msgid "Searching"
msgstr "Ricerca in corso"
#: gitk:4767
msgid "Tags:"
msgstr "Etichette:"
#: gitk:4784 gitk:4790 gitk:5951
msgid "Parent"
msgstr "Genitore"
#: gitk:4795
msgid "Child"
msgstr "Figlio"
#: gitk:4804
msgid "Branch"
msgstr "Ramo"
#: gitk:4807
msgid "Follows"
msgstr "Segue"
#: gitk:4810
msgid "Precedes"
msgstr "Precede"
#: gitk:5093
msgid "Error getting merge diffs:"
msgstr "Errore nella lettura delle differenze di fusione:"
#: gitk:5778
msgid "Goto:"
msgstr "Vai a:"
#: gitk:5780
msgid "SHA1 ID:"
msgstr "SHA1 ID:"
#: gitk:5805
#, tcl-format
msgid "Short SHA1 id %s is ambiguous"
msgstr "La SHA1 id abbreviata %s è ambigua"
#: gitk:5817
#, tcl-format
msgid "SHA1 id %s is not known"
msgstr "La SHA1 id %s è sconosciuta"
#: gitk:5819
#, tcl-format
msgid "Tag/Head %s is not known"
msgstr "L'etichetta/ramo %s è sconosciuto"
#: gitk:5961
msgid "Children"
msgstr "Figli"
#: gitk:6018
#, tcl-format
msgid "Reset %s branch to here"
msgstr "Aggiorna il ramo %s a questa revisione"
#: gitk:6049
msgid "Top"
msgstr "Inizio"
#: gitk:6050
msgid "From"
msgstr "Da"
#: gitk:6055
msgid "To"
msgstr "A"
#: gitk:6078
msgid "Generate patch"
msgstr "Genera patch"
#: gitk:6080
msgid "From:"
msgstr "Da:"
#: gitk:6089
msgid "To:"
msgstr "A:"
#: gitk:6098
msgid "Reverse"
msgstr "Inverti"
#: gitk:6100 gitk:6269
msgid "Output file:"
msgstr "Scrivi sul file:"
#: gitk:6106
msgid "Generate"
msgstr "Genera"
#: gitk:6142
msgid "Error creating patch:"
msgstr "Errore nella creazione della patch:"
#: gitk:6164 gitk:6257 gitk:6311
msgid "ID:"
msgstr "ID:"
#: gitk:6173
msgid "Tag name:"
msgstr "Nome etichetta:"
#: gitk:6177 gitk:6320
msgid "Create"
msgstr "Crea"
#: gitk:6192
msgid "No tag name specified"
msgstr "Nessuna etichetta specificata"
#: gitk:6196
#, tcl-format
msgid "Tag \"%s\" already exists"
msgstr "L'etichetta \"%s\" esiste già"
#: gitk:6202
msgid "Error creating tag:"
msgstr "Errore nella creazione dell'etichetta:"
#: gitk:6266
msgid "Command:"
msgstr "Comando:"
#: gitk:6274
msgid "Write"
msgstr "Scrivi"
#: gitk:6290
msgid "Error writing commit:"
msgstr "Errore nella scrittura della revisione:"
#: gitk:6316
msgid "Name:"
msgstr "Nome:"
#: gitk:6335
msgid "Please specify a name for the new branch"
msgstr "Specificare un nome per il nuovo ramo"
#: gitk:6364
#, tcl-format
msgid "Commit %s is already included in branch %s -- really re-apply it?"
msgstr "La revisione %s è già inclusa nel ramo %s -- applicarla di nuovo?"
#: gitk:6369
msgid "Cherry-picking"
msgstr ""
#: gitk:6381
msgid "No changes committed"
msgstr "Nessuna modifica archiviata"
#: gitk:6404
msgid "Confirm reset"
msgstr "Conferma git reset"
#: gitk:6406
#, tcl-format
msgid "Reset branch %s to %s?"
msgstr "Aggiornare il ramo %s a %s?"
#: gitk:6410
msgid "Reset type:"
msgstr "Tipo di aggiornamento:"
#: gitk:6414
msgid "Soft: Leave working tree and index untouched"
msgstr "Soft: Lascia la direcory di lavoro e l'indice come sono"
#: gitk:6417
msgid "Mixed: Leave working tree untouched, reset index"
msgstr "Mixed: Lascia la directory di lavoro come è, aggiorna l'indice"
#: gitk:6420
msgid ""
"Hard: Reset working tree and index\n"
"(discard ALL local changes)"
msgstr ""
"Hard: Aggiorna la directory di lavoro e l'indice\n"
"(abbandona TUTTE le modifiche locali)"
#: gitk:6436
msgid "Resetting"
msgstr "git reset in corso"
#: gitk:6493
msgid "Checking out"
msgstr "Attivazione in corso"
#: gitk:6523
msgid "Cannot delete the currently checked-out branch"
msgstr "Impossibile cancellare il ramo attualmente attivo"
#: gitk:6529
#, tcl-format
msgid ""
"The commits on branch %s aren't on any other branch.\n"
"Really delete branch %s?"
msgstr ""
"Le revisioni nel ramo %s non sono presenti su altri rami.\n"
"Cancellare il ramo %s?"
#: gitk:6560
#, tcl-format
msgid "Tags and heads: %s"
msgstr "Etichette e rami: %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 ""
"Errore nella lettura della topologia delle revisioni: le informazioni sul "
"ramo e le etichette precedenti e seguenti saranno incomplete."
#: gitk:7852
msgid "Tag"
msgstr "Etichetta"
#: gitk:7852
msgid "Id"
msgstr "Id"
#: gitk:7892
msgid "Gitk font chooser"
msgstr "Scelta caratteri gitk"
#: gitk:7909
msgid "B"
msgstr "B"
#: gitk:7912
msgid "I"
msgstr "I"
#: gitk:8005
msgid "Gitk preferences"
msgstr "Preferenze gitk"
#: gitk:8006
msgid "Commit list display options"
msgstr "Opzioni visualizzazione dell'elenco revisioni"
#: gitk:8009
msgid "Maximum graph width (lines)"
msgstr "Larghezza massima del grafico (in linee)"
#: gitk:8013
#, tcl-format
msgid "Maximum graph width (% of pane)"
msgstr "Larghezza massima del grafico (% del pannello)"
#: gitk:8018
msgid "Show local changes"
msgstr "Mostra modifiche locali"
#: gitk:8023
msgid "Auto-select SHA1"
msgstr "Seleziona automaticamente SHA1 hash"
#: gitk:8028
msgid "Diff display options"
msgstr "Opzioni di visualizzazione delle differenze"
#: gitk:8030
msgid "Tab spacing"
msgstr "Spaziatura tabulazioni"
#: gitk:8034
msgid "Display nearby tags"
msgstr "Mostra etichette vicine"
#: gitk:8039
msgid "Limit diffs to listed paths"
msgstr "Limita le differenze ai percorsi elencati"
#: gitk:8044
msgid "Colors: press to choose"
msgstr "Colori: premere per scegliere"
#: gitk:8047
msgid "Background"
msgstr "Sfondo"
#: gitk:8051
msgid "Foreground"
msgstr "Primo piano"
#: gitk:8055
msgid "Diff: old lines"
msgstr "Diff: vecchie linee"
#: gitk:8060
msgid "Diff: new lines"
msgstr "Diff: nuove linee"
#: gitk:8065
msgid "Diff: hunk header"
msgstr "Diff: intestazione della sezione"
#: gitk:8071
msgid "Select bg"
msgstr "Sfondo selezione"
#: gitk:8075
msgid "Fonts: press to choose"
msgstr "Carattere: premere per scegliere"
#: gitk:8077
msgid "Main font"
msgstr "Carattere principale"
#: gitk:8078
msgid "Diff display font"
msgstr "Carattere per differenze"
#: gitk:8079
msgid "User interface font"
msgstr "Carattere per interfaccia utente"
#: gitk:8095
#, tcl-format
msgid "Gitk: choose color for %s"
msgstr "Gitk: scegliere un colore per %s"
#: gitk:8476
msgid ""
"Sorry, gitk cannot run with this version of Tcl/Tk.\n"
" Gitk requires at least Tcl/Tk 8.4."
msgstr ""
"Questa versione di Tcl/Tk non può avviare gitk.\n"
" Gitk richiede Tcl/Tk versione 8.4 o superiore."
#: gitk:8565
msgid "Cannot find a git repository here."
msgstr "Archivio git non trovato."
#: gitk:8569
#, tcl-format
msgid "Cannot find the git directory \"%s\"."
msgstr "Directory git \"%s\" non trovata."
#: gitk:8612
#, tcl-format
msgid "Ambiguous argument '%s': both revision and filename"
msgstr "Argomento ambiguo: '%s' è sia revisione che nome di file"
#: gitk:8624
msgid "Bad arguments to gitk:"
msgstr "Gitk: argomenti errati:"
#: gitk:8636
msgid "Couldn't get list of unmerged files:"
msgstr "Impossibile ottenere l'elenco dei file in attesa di fusione:"
#: gitk:8652
msgid "No files selected: --merge specified but no files are unmerged."
msgstr ""
"Nessun file selezionato: è stata specificata l'opzione --merge ma non ci "
"sono file in attesa di fusione."
#: gitk:8655
msgid ""
"No files selected: --merge specified but no unmerged files are within file "
"limit."
msgstr ""
"Nessun file selezionato: è stata specificata l'opzione --merge ma i file "
"specificati non sono in attesa di fusione."
#: gitk:8716
msgid "Command line"
msgstr "Linea di comando"

116
help.c
View File

@@ -8,6 +8,12 @@
#include "exec_cmd.h"
#include "common-cmds.h"
#include "parse-options.h"
#include "run-command.h"
static struct man_viewer_list {
void (*exec)(const char *);
struct man_viewer_list *next;
} *man_viewer_list;
enum help_format {
HELP_FORMAT_MAN,
@@ -42,6 +48,102 @@ static enum help_format parse_help_format(const char *format)
die("unrecognized help format '%s'", format);
}
static int check_emacsclient_version(void)
{
struct strbuf buffer = STRBUF_INIT;
struct child_process ec_process;
const char *argv_ec[] = { "emacsclient", "--version", NULL };
int version;
/* emacsclient prints its version number on stderr */
memset(&ec_process, 0, sizeof(ec_process));
ec_process.argv = argv_ec;
ec_process.err = -1;
ec_process.stdout_to_stderr = 1;
if (start_command(&ec_process)) {
fprintf(stderr, "Failed to start emacsclient.\n");
return -1;
}
strbuf_read(&buffer, ec_process.err, 20);
close(ec_process.err);
/*
* Don't bother checking return value, because "emacsclient --version"
* seems to always exits with code 1.
*/
finish_command(&ec_process);
if (prefixcmp(buffer.buf, "emacsclient")) {
fprintf(stderr, "Failed to parse emacsclient version.\n");
strbuf_release(&buffer);
return -1;
}
strbuf_remove(&buffer, 0, strlen("emacsclient"));
version = atoi(buffer.buf);
if (version < 22) {
fprintf(stderr,
"emacsclient version '%d' too old (< 22).\n",
version);
strbuf_release(&buffer);
return -1;
}
strbuf_release(&buffer);
return 0;
}
static void exec_woman_emacs(const char *page)
{
if (!check_emacsclient_version()) {
/* This works only with emacsclient version >= 22. */
struct strbuf man_page = STRBUF_INIT;
strbuf_addf(&man_page, "(woman \"%s\")", page);
execlp("emacsclient", "emacsclient", "-e", man_page.buf, NULL);
}
}
static void exec_man_konqueror(const char *page)
{
const char *display = getenv("DISPLAY");
if (display && *display) {
struct strbuf man_page = STRBUF_INIT;
strbuf_addf(&man_page, "man:%s(1)", page);
execlp("kfmclient", "kfmclient", "newTab", man_page.buf, NULL);
}
}
static void exec_man_man(const char *page)
{
execlp("man", "man", page, NULL);
}
static void do_add_man_viewer(void (*exec)(const char *))
{
struct man_viewer_list **p = &man_viewer_list;
while (*p)
p = &((*p)->next);
*p = xmalloc(sizeof(**p));
(*p)->next = NULL;
(*p)->exec = exec;
}
static int add_man_viewer(const char *value)
{
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 0;
}
static int git_help_config(const char *var, const char *value)
{
if (!strcmp(var, "help.format")) {
@@ -50,6 +152,11 @@ static int git_help_config(const char *var, const char *value)
help_format = parse_help_format(value);
return 0;
}
if (!strcmp(var, "man.viewer")) {
if (!value)
return config_error_nonbool(var);
return add_man_viewer(value);
}
return git_default_config(var, value);
}
@@ -370,9 +477,16 @@ static void setup_man_path(void)
static void show_man_page(const char *git_cmd)
{
struct man_viewer_list *viewer;
const char *page = cmd_to_page(git_cmd);
setup_man_path();
execlp("man", "man", page, NULL);
for (viewer = man_viewer_list; viewer; viewer = viewer->next)
{
viewer->exec(page); /* will return when unable */
}
exec_man_man(page);
die("no man viewer handled the request");
}
static void show_info_page(const char *git_cmd)

View File

@@ -138,10 +138,14 @@ static int has_non_ascii(const char *s)
}
void log_write_email_headers(struct rev_info *opt, const char *name,
const char **subject_p, const char **extra_headers_p)
const char **subject_p,
const char **extra_headers_p,
int *need_8bit_cte_p)
{
const char *subject = NULL;
const char *extra_headers = opt->extra_headers;
*need_8bit_cte_p = 0; /* unknown */
if (opt->total > 0) {
static char buffer[64];
snprintf(buffer, sizeof(buffer),
@@ -169,6 +173,7 @@ void log_write_email_headers(struct rev_info *opt, const char *name,
if (opt->mime_boundary) {
static char subject_buffer[1024];
static char buffer[1024];
*need_8bit_cte_p = -1; /* NEVER */
snprintf(subject_buffer, sizeof(subject_buffer) - 1,
"%s"
"MIME-Version: 1.0\n"
@@ -212,6 +217,7 @@ void show_log(struct rev_info *opt, const char *sep)
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;
opt->loginfo = NULL;
if (!opt->verbose_header) {
@@ -255,7 +261,8 @@ void show_log(struct rev_info *opt, const char *sep)
if (opt->commit_format == CMIT_FMT_EMAIL) {
log_write_email_headers(opt, sha1_to_hex(commit->object.sha1),
&subject, &extra_headers);
&subject, &extra_headers,
&need_8bit_cte);
} else if (opt->commit_format != CMIT_FMT_USERFORMAT) {
fputs(diff_get_color_opt(&opt->diffopt, DIFF_COMMIT), stdout);
if (opt->commit_format != CMIT_FMT_ONELINE)
@@ -299,9 +306,11 @@ void show_log(struct rev_info *opt, const char *sep)
* And then the pretty-printed message itself
*/
strbuf_init(&msgbuf, 0);
if (need_8bit_cte >= 0)
need_8bit_cte = has_non_ascii(opt->add_signoff);
pretty_print_commit(opt->commit_format, commit, &msgbuf,
abbrev, subject, extra_headers, opt->date_mode,
has_non_ascii(opt->add_signoff));
need_8bit_cte);
if (opt->add_signoff)
append_signoff(&msgbuf, opt->add_signoff);

View File

@@ -14,6 +14,8 @@ int log_tree_opt_parse(struct rev_info *, const char **, int);
void show_log(struct rev_info *opt, const char *sep);
void show_decorations(struct commit *commit);
void log_write_email_headers(struct rev_info *opt, const char *name,
const char **subject_p, const char **extra_headers_p);
const char **subject_p,
const char **extra_headers_p,
int *need_8bit_cte_p);
#endif

View File

@@ -636,7 +636,7 @@ void pp_title_line(enum cmit_fmt fmt,
const char *subject,
const char *after_subject,
const char *encoding,
int plain_non_ascii)
int need_8bit_cte)
{
struct strbuf title;
@@ -669,7 +669,7 @@ void pp_title_line(enum cmit_fmt fmt,
}
strbuf_addch(sb, '\n');
if (plain_non_ascii) {
if (need_8bit_cte > 0) {
const char *header_fmt =
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=%s\n"
@@ -718,9 +718,9 @@ void pp_remainder(enum cmit_fmt fmt,
}
void pretty_print_commit(enum cmit_fmt fmt, const struct commit *commit,
struct strbuf *sb, int abbrev,
const char *subject, const char *after_subject,
enum date_mode dmode, int plain_non_ascii)
struct strbuf *sb, int abbrev,
const char *subject, const char *after_subject,
enum date_mode dmode, int need_8bit_cte)
{
unsigned long beginning_of_body;
int indent = 4;
@@ -746,13 +746,11 @@ void pretty_print_commit(enum cmit_fmt fmt, const struct commit *commit,
if (fmt == CMIT_FMT_ONELINE || fmt == CMIT_FMT_EMAIL)
indent = 0;
/* After-subject is used to pass in Content-Type: multipart
* MIME header; in that case we do not have to do the
* plaintext content type even if the commit message has
* non 7-bit ASCII character. Otherwise, check if we need
* to say this is not a 7-bit ASCII.
/*
* We need to check and emit Content-type: to mark it
* as 8-bit if we haven't done so.
*/
if (fmt == CMIT_FMT_EMAIL && !after_subject) {
if (fmt == CMIT_FMT_EMAIL && need_8bit_cte == 0) {
int i, ch, in_body;
for (in_body = i = 0; (ch = msg[i]); i++) {
@@ -765,7 +763,7 @@ void pretty_print_commit(enum cmit_fmt fmt, const struct commit *commit,
in_body = 1;
}
else if (non_ascii(ch)) {
plain_non_ascii = 1;
need_8bit_cte = 1;
break;
}
}
@@ -790,7 +788,7 @@ void pretty_print_commit(enum cmit_fmt fmt, const struct commit *commit,
/* These formats treat the title line specially. */
if (fmt == CMIT_FMT_ONELINE || fmt == CMIT_FMT_EMAIL)
pp_title_line(fmt, &msg, sb, subject,
after_subject, encoding, plain_non_ascii);
after_subject, encoding, need_8bit_cte);
beginning_of_body = sb->len;
if (fmt != CMIT_FMT_ONELINE)

View File

@@ -407,18 +407,22 @@ static int get_nth_ancestor(const char *name, int len,
unsigned char *result, int generation)
{
unsigned char sha1[20];
int ret = get_sha1_1(name, len, sha1);
struct commit *commit;
int ret;
ret = get_sha1_1(name, len, sha1);
if (ret)
return ret;
commit = lookup_commit_reference(sha1);
if (!commit)
return -1;
while (generation--) {
struct commit *commit = lookup_commit_reference(sha1);
if (!commit || parse_commit(commit) || !commit->parents)
if (parse_commit(commit) || !commit->parents)
return -1;
hashcpy(sha1, commit->parents->item->object.sha1);
commit = commit->parents->item;
}
hashcpy(result, sha1);
hashcpy(result, commit->object.sha1);
return 0;
}
@@ -544,9 +548,8 @@ static int get_sha1_1(const char *name, int len, unsigned char *sha1)
int ret, has_suffix;
const char *cp;
/* "name~3" is "name^^^",
* "name~" and "name~0" are name -- not "name^0"!
* "name^" is not "name^0"; it is "name^1".
/*
* "name~3" is "name^^^", "name~" is "name~1", and "name^" is "name^1".
*/
has_suffix = 0;
for (cp = name + len - 1; name <= cp; cp--) {
@@ -564,11 +567,10 @@ static int get_sha1_1(const char *name, int len, unsigned char *sha1)
cp++;
while (cp < name + len)
num = num * 10 + *cp++ - '0';
if (has_suffix == '^') {
if (!num && len1 == len - 1)
num = 1;
if (!num && len1 == len - 1)
num = 1;
if (has_suffix == '^')
return get_parent(name, len1, sha1, num);
}
/* else if (has_suffix == '~') -- goes without saying */
return get_nth_ancestor(name, len1, sha1, num);
}

View File

@@ -21,8 +21,8 @@ compare_diff_raw_z () {
# Also we do not check SHA1 hash generation in this test, which
# is a job for t0000-basic.sh
tr '\000' '\012' <"$1" | sed -e "$sanitize_diff_raw_z" >.tmp-1
tr '\000' '\012' <"$2" | sed -e "$sanitize_diff_raw_z" >.tmp-2
perl -pe 'y/\000/\012/' <"$1" | sed -e "$sanitize_diff_raw_z" >.tmp-1
perl -pe 'y/\000/\012/' <"$2" | sed -e "$sanitize_diff_raw_z" >.tmp-2
git diff .tmp-1 .tmp-2 && rm -f .tmp-1 .tmp-2
}

View File

@@ -11,7 +11,7 @@ attr_check () {
git check-attr test -- "$path" >actual &&
echo "$path: test: $2" >expect &&
diff -u expect actual
test_cmp expect actual
}

View File

@@ -5,7 +5,7 @@ test_description='CRLF conversion'
. ./test-lib.sh
q_to_nul () {
tr Q '\000'
perl -pe 'y/Q/\000/'
}
q_to_cr () {

View File

@@ -26,7 +26,7 @@ test_expect_success 'diff -M' '
git diff-tree -M -r --name-status HEAD^ HEAD |
sed -e "s/R[0-9]*/RNUM/" >actual &&
echo "RNUM sample elpmas" >expect &&
echo "RNUM sample elpmas" >expect &&
test_cmp expect actual
'

View File

@@ -245,12 +245,12 @@ test_expect_success \
test_expect_success \
'text plus spaces without newline at end should not show spaces' '
! (printf "$ttt$sss" | git stripspace | grep -q " ") &&
! (printf "$ttt$ttt$sss" | git stripspace | grep -q " ") &&
! (printf "$ttt$ttt$ttt$sss" | git stripspace | grep -q " ") &&
! (printf "$ttt$sss$sss" | git stripspace | grep -q " ") &&
! (printf "$ttt$ttt$sss$sss" | git stripspace | grep -q " ") &&
! (printf "$ttt$sss$sss$sss" | git stripspace | grep -q " ")
! (printf "$ttt$sss" | git stripspace | grep " " >/dev/null) &&
! (printf "$ttt$ttt$sss" | git stripspace | grep " " >/dev/null) &&
! (printf "$ttt$ttt$ttt$sss" | git stripspace | grep " " >/dev/null) &&
! (printf "$ttt$sss$sss" | git stripspace | grep " " >/dev/null) &&
! (printf "$ttt$ttt$sss$sss" | git stripspace | grep " " >/dev/null) &&
! (printf "$ttt$sss$sss$sss" | git stripspace | grep " " >/dev/null)
'
test_expect_success \
@@ -282,12 +282,12 @@ test_expect_success \
test_expect_success \
'text plus spaces at end should not show spaces' '
! (echo "$ttt$sss" | git stripspace | grep -q " ") &&
! (echo "$ttt$ttt$sss" | git stripspace | grep -q " ") &&
! (echo "$ttt$ttt$ttt$sss" | git stripspace | grep -q " ") &&
! (echo "$ttt$sss$sss" | git stripspace | grep -q " ") &&
! (echo "$ttt$ttt$sss$sss" | git stripspace | grep -q " ") &&
! (echo "$ttt$sss$sss$sss" | git stripspace | grep -q " ")
! (echo "$ttt$sss" | git stripspace | grep " " >/dev/null) &&
! (echo "$ttt$ttt$sss" | git stripspace | grep " " >/dev/null) &&
! (echo "$ttt$ttt$ttt$sss" | git stripspace | grep " " >/dev/null) &&
! (echo "$ttt$sss$sss" | git stripspace | grep " " >/dev/null) &&
! (echo "$ttt$ttt$sss$sss" | git stripspace | grep " " >/dev/null) &&
! (echo "$ttt$sss$sss$sss" | git stripspace | grep " " >/dev/null)
'
test_expect_success \
@@ -341,11 +341,11 @@ test_expect_success \
test_expect_success \
'spaces without newline at end should not show spaces' '
! (printf "" | git stripspace | grep -q " ") &&
! (printf "$sss" | git stripspace | grep -q " ") &&
! (printf "$sss$sss" | git stripspace | grep -q " ") &&
! (printf "$sss$sss$sss" | git stripspace | grep -q " ") &&
! (printf "$sss$sss$sss$sss" | git stripspace | grep -q " ")
! (printf "" | git stripspace | grep " " >/dev/null) &&
! (printf "$sss" | git stripspace | grep " " >/dev/null) &&
! (printf "$sss$sss" | git stripspace | grep " " >/dev/null) &&
! (printf "$sss$sss$sss" | git stripspace | grep " " >/dev/null) &&
! (printf "$sss$sss$sss$sss" | git stripspace | grep " " >/dev/null)
'
test_expect_success \

View File

@@ -4,8 +4,8 @@ test_description='Various filesystem issues'
. ./test-lib.sh
auml=`perl -CO -e 'print pack("U",0x00E4)'`
aumlcdiar=`perl -CO -e 'print pack("U",0x0061).pack("U",0x0308)'`
auml=`printf '\xc3\xa4'`
aumlcdiar=`printf '\x61\xcc\x88'`
test_expect_success 'see if we expect ' '

View File

@@ -24,7 +24,7 @@ test_expect_success 'setup' '
test_expect_success 'reset should work' '
git read-tree -u --reset HEAD^ &&
git ls-files >actual &&
diff -u expect actual
test_cmp expect actual
'
test_done

View File

@@ -657,12 +657,12 @@ Qsection.sub=section.val4
Qsection.sub=section.val5Q
EOF
git config --null --list | tr '\000' 'Q' > result
git config --null --list | perl -pe 'y/\000/Q/' > result
echo >>result
test_expect_success '--null --list' 'cmp result expect'
git config --null --get-regexp 'val[0-9]' | tr '\000' 'Q' > result
git config --null --get-regexp 'val[0-9]' | perl -pe 'y/\000/Q/' > result
echo >>result
test_expect_success '--null --get-regexp' 'cmp result expect'

View File

@@ -202,22 +202,4 @@ test_expect_success 'delete' '
'
test_expect_success 'prune --expire' '
before=$(git count-objects | sed "s/ .*//") &&
BLOB=$(echo aleph | git hash-object -w --stdin) &&
BLOB_FILE=.git/objects/$(echo $BLOB | sed "s/^../&\//") &&
test $((1 + $before)) = $(git count-objects | sed "s/ .*//") &&
test -f $BLOB_FILE &&
git reset --hard &&
git prune --expire=1.hour.ago &&
test $((1 + $before)) = $(git count-objects | sed "s/ .*//") &&
test -f $BLOB_FILE &&
test-chmtime -86500 $BLOB_FILE &&
git prune --expire 1.day &&
test $before = $(git count-objects | sed "s/ .*//") &&
! test -f $BLOB_FILE
'
test_done

View File

@@ -62,7 +62,7 @@ test_expect_success 'cache tree has not been corrupted' '
sed -e "s/ 0 / /" >expect &&
git ls-tree -r $(git write-tree) |
sed -e "s/ blob / /" >current &&
diff -u expect current
test_cmp expect current
'

View File

@@ -97,7 +97,7 @@ cat > expect << EOF
EOF
test_expect_success 'git-status honours core.excludesfile' \
'diff -u expect output'
'test_cmp expect output'
test_expect_success 'trailing slash in exclude allows directory match(1)' '

View File

@@ -26,7 +26,7 @@ test_expect_success clone '
cd cloned &&
(git rev-parse HEAD; git ls-files -s) >../actual
) &&
diff -u expected actual
test_cmp expected actual
'
test_expect_success advance '
@@ -46,7 +46,7 @@ test_expect_success fetch '
git pull &&
(git rev-parse HEAD; git ls-files -s) >../actual
) &&
diff -u expected actual
test_cmp expected actual
'
test_done

View File

@@ -66,6 +66,6 @@ test_expect_success 'git -ls-files --with-tree should succeed from subdir' '
cd ..
test_expect_success \
'git -ls-files --with-tree should add entries from named tree.' \
'diff -u expected output'
'test_cmp expected output'
test_done

View File

@@ -31,7 +31,7 @@ test_expect_success 'branch --contains=master' '
{
echo " master" && echo "* side"
} >expect &&
diff -u expect actual
test_cmp expect actual
'
@@ -41,7 +41,7 @@ test_expect_success 'branch --contains master' '
{
echo " master" && echo "* side"
} >expect &&
diff -u expect actual
test_cmp expect actual
'
@@ -51,7 +51,7 @@ test_expect_success 'branch --contains=side' '
{
echo "* side"
} >expect &&
diff -u expect actual
test_cmp expect actual
'

View File

@@ -54,7 +54,7 @@ echo 'just space
no-funny
tabs ," (dq) and spaces' >expected
test_expect_success 'git ls-files -z with-funny' \
'git ls-files -z | tr \\000 \\012 >current &&
'git ls-files -z | perl -pe y/\\000/\\012/ >current &&
git diff expected current'
t1=`git write-tree`
@@ -83,11 +83,11 @@ test_expect_success 'git diff-tree with-funny' \
echo 'A
tabs ," (dq) and spaces' >expected
test_expect_success 'git diff-index -z with-funny' \
'git diff-index -z --name-status $t0 | tr \\000 \\012 >current &&
'git diff-index -z --name-status $t0 | perl -pe y/\\000/\\012/ >current &&
git diff expected current'
test_expect_success 'git diff-tree -z with-funny' \
'git diff-tree -z --name-status $t0 $t1 | tr \\000 \\012 >current &&
'git diff-tree -z --name-status $t0 $t1 | perl -pe y/\\000/\\012/ >current &&
git diff expected current'
cat > expected <<\EOF

View File

@@ -122,8 +122,8 @@ test_expect_success 'reflog for the branch shows state before rebase' '
test_expect_success 'exchange two commits' '
FAKE_LINES="2 1" git rebase -i HEAD~2 &&
test H = $(git cat-file commit HEAD^ | tail -n 1) &&
test G = $(git cat-file commit HEAD | tail -n 1)
test H = $(git cat-file commit HEAD^ | sed -ne \$p) &&
test G = $(git cat-file commit HEAD | sed -ne \$p)
'
cat > expect << EOF
@@ -146,11 +146,10 @@ EOF
test_expect_success 'stop on conflicting pick' '
git tag new-branch1 &&
! git rebase -i master &&
diff -u expect .git/.dotest-merge/patch &&
diff -u expect2 file1 &&
test_cmp expect .git/.dotest-merge/patch &&
test_cmp expect2 file1 &&
test 4 = $(grep -v "^#" < .git/.dotest-merge/done | wc -l) &&
test 0 = $(grep -ve "^#" -e "^$" < .git/.dotest-merge/git-rebase-todo |
wc -l)
test 0 = $(grep -c "^[^#]" < .git/.dotest-merge/git-rebase-todo)
'
test_expect_success 'abort' '

View File

@@ -41,8 +41,8 @@ test_expect_success rebase '
git rebase master side &&
git cat-file commit HEAD | sed -e "1,/^\$/d" >F1 &&
diff -u F0 F1 &&
diff -u F F0
test_cmp F0 F1 &&
test_cmp F F0
'
test_done

View File

@@ -37,7 +37,7 @@ test_expect_success 'rebase -m' '
git rebase -m master >report &&
sed -n -e "/^Already applied: /p" \
-e "/^Committed: /p" report >actual &&
diff -u expect actual
test_cmp expect actual
'

View File

@@ -24,7 +24,7 @@ EOF
test_expect_success 'diff works (initial)' '
(echo d; echo 1) | git add -i >output &&
sed -ne "/new file/,/content/p" <output >diff &&
diff -u expected diff
test_cmp expected diff
'
test_expect_success 'revert works (initial)' '
git add file &&
@@ -57,7 +57,7 @@ EOF
test_expect_success 'diff works (commit)' '
(echo d; echo 1) | git add -i >output &&
sed -ne "/^index/,/content/p" <output >diff &&
diff -u expected diff
test_cmp expected diff
'
test_expect_success 'revert works (commit)' '
git add file &&

View File

@@ -15,7 +15,7 @@ check_verify_failure () {
expect="$2"
test_expect_success "$1" '
( ! git-mktag <tag.sig 2>message ) &&
grep -q "$expect" message
grep "$expect" message
'
}

View File

@@ -78,28 +78,28 @@ EOF
test_expect_success 'check fully quoted output from ls-files' '
git ls-files >current && diff -u expect.quoted current
git ls-files >current && test_cmp expect.quoted current
'
test_expect_success 'check fully quoted output from diff-files' '
git diff --name-only >current &&
diff -u expect.quoted current
test_cmp expect.quoted current
'
test_expect_success 'check fully quoted output from diff-index' '
git diff --name-only HEAD >current &&
diff -u expect.quoted current
test_cmp expect.quoted current
'
test_expect_success 'check fully quoted output from diff-tree' '
git diff --name-only HEAD^ HEAD >current &&
diff -u expect.quoted current
test_cmp expect.quoted current
'
@@ -111,28 +111,28 @@ test_expect_success 'setting core.quotepath' '
test_expect_success 'check fully quoted output from ls-files' '
git ls-files >current && diff -u expect.raw current
git ls-files >current && test_cmp expect.raw current
'
test_expect_success 'check fully quoted output from diff-files' '
git diff --name-only >current &&
diff -u expect.raw current
test_cmp expect.raw current
'
test_expect_success 'check fully quoted output from diff-index' '
git diff --name-only HEAD >current &&
diff -u expect.raw current
test_cmp expect.raw current
'
test_expect_success 'check fully quoted output from diff-tree' '
git diff --name-only HEAD^ HEAD >current &&
diff -u expect.raw current
test_cmp expect.raw current
'

View File

@@ -34,7 +34,7 @@ EOF
test_expect_success 'parents of stash' '
test $(git rev-parse stash^) = $(git rev-parse HEAD) &&
git diff stash^2..stash > output &&
diff -u output expect
test_cmp output expect
'
test_expect_success 'apply needs clean working directory' '

View File

@@ -99,11 +99,12 @@ test_expect_success 'no diff with -diff' '
git diff | grep Binary
'
echo NULZbetweenZwords | tr Z '\000' > file
echo NULZbetweenZwords | perl -pe 'y/Z/\000/' > file
test_expect_success 'force diff with "diff"' '
echo >.gitattributes "file diff" &&
git diff | grep -a second
git diff >actual &&
test_cmp ../t4020/diff.NUL actual
'
test_done

BIN
t/t4020/diff.NUL Normal file

Binary file not shown.

View File

@@ -32,11 +32,19 @@ test_expect_success 'format with signoff without funny signer name' '
test_expect_success 'format with non ASCII signer name' '
GIT_COMMITTER_NAME="$B$O$^$N(B $B$U$K$*$&(B" \
GIT_COMMITTER_NAME="はまの ふにおう" \
git format-patch -s --stdout -1 >output &&
grep Content-Type output
'
test_expect_success 'attach and signoff do not duplicate mime headers' '
GIT_COMMITTER_NAME="はまの ふにおう" \
git format-patch -s --stdout -1 --attach >output &&
test `grep -ci ^MIME-Version: output` = 1
'
test_done

View File

@@ -8,7 +8,10 @@ test_expect_success setup '
cat ../../COPYING >test &&
git add test &&
tr 'a-zA-Z' 'n-za-mN-ZA-M' <../../COPYING >test
tr \
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" \
"nopqrstuvwxyzabcdefghijklmNOPQRSTUVWXYZABCDEFGHIJKLM" \
<../../COPYING >test
'

View File

@@ -62,7 +62,7 @@ test_expect_success 'cross renames to be detected for regular files' '
echo "R100 foo bar"
echo "R100 bar foo"
} | sort >expect &&
diff -u expect actual
test_cmp expect actual
'
@@ -73,7 +73,7 @@ test_expect_success 'cross renames to be detected for typechange' '
echo "R100 foo bar"
echo "R100 bar foo"
} | sort >expect &&
diff -u expect actual
test_cmp expect actual
'
@@ -84,7 +84,7 @@ test_expect_success 'moves and renames' '
echo "R100 foo bar"
echo "T100 foo"
} | sort >expect &&
diff -u expect actual
test_cmp expect actual
'

View File

@@ -150,7 +150,7 @@ test_expect_success 'diff -U0' '
do
git diff -U0 file-?$n
done | zc >actual &&
diff -u expect actual
test_cmp expect actual
'

View File

@@ -37,7 +37,7 @@ test_expect_success 'hunk header truncation with an overly long line' '
echo " A $N$N$N$N$N$N$N$N$N2"
echo " L $N$N$N$N$N$N$N$N$N1"
) >expected &&
diff -u actual expected
test_cmp actual expected
'

View File

@@ -37,17 +37,17 @@ test_expect_success setup '
test_expect_success 'git diff --raw HEAD' '
git diff --raw --abbrev=40 HEAD >actual &&
diff -u expect actual
test_cmp expect actual
'
test_expect_success 'git diff-index --raw HEAD' '
git diff-index --raw HEAD >actual.index &&
diff -u expect actual.index
test_cmp expect actual.index
'
test_expect_success 'git diff-files --raw' '
git diff-files --raw >actual.files &&
diff -u expect actual.files
test_cmp expect actual.files
'
test_done

View File

@@ -0,0 +1,30 @@
#!/bin/sh
test_description='format-patch mime headers and extra headers do not conflict'
. ./test-lib.sh
test_expect_success 'create commit with utf-8 body' '
echo content >file &&
git add file &&
git commit -m one &&
echo more >>file &&
git commit -a -m "two
utf-8 body: ñ"
'
test_expect_success 'patch has mime headers' '
rm -f 0001-two.patch &&
git format-patch HEAD^ &&
grep -i "content-type: text/plain; charset=utf-8" 0001-two.patch
'
test_expect_success 'patch has mime and extra headers' '
rm -f 0001-two.patch &&
git config format.headers "x-foo: bar" &&
git format-patch HEAD^ &&
grep -i "x-foo: bar" 0001-two.patch &&
grep -i "content-type: text/plain; charset=utf-8" 0001-two.patch
'
test_done

View File

@@ -24,10 +24,10 @@ git update-index --add --remove file1 file2 file4
git-commit -m 'Initial Version' 2>/dev/null
git-checkout -b binary
tr 'x' '\000' <file1 >file3
perl -pe 'y/x/\000/' <file1 >file3
cat file3 >file4
git add file2
tr '\000' 'v' <file3 >file1
perl -pe 'y/\000/v/' <file3 >file1
rm -f file2
git update-index --add --remove file1 file2 file3 file4
git-commit -m 'Second Version'

View File

@@ -9,7 +9,7 @@ dotest () {
test_expect_success "$name" "
git checkout-index -f -q -u file &&
git apply $* &&
diff -u expect file
test_cmp expect file
"
}

View File

@@ -12,14 +12,14 @@ test_description='git apply in reverse
test_expect_success setup '
for i in a b c d e f g h i j k l m n; do echo $i; done >file1 &&
tr "ijk" '\''\000\001\002'\'' <file1 >file2 &&
perl -pe "y/ijk/\\000\\001\\002/" <file1 >file2 &&
git add file1 file2 &&
git commit -m initial &&
git tag initial &&
for i in a b c g h i J K L m o n p q; do echo $i; done >file1 &&
tr "mon" '\''\000\001\002'\'' <file1 >file2 &&
perl -pe "y/mon/\\000\\001\\002/" <file1 >file2 &&
git commit -a -m second &&
git tag second &&

View File

@@ -56,7 +56,7 @@ test_expect_success nofix '
git apply --whitespace=nowarn patch-1 &&
# The result should obviously match.
diff -u file-1 file
test_cmp file-1 file
'
test_expect_success 'withfix (forward)' '
@@ -70,7 +70,7 @@ test_expect_success 'withfix (forward)' '
git apply --whitespace=fix patch-0 &&
git apply --whitespace=fix patch-1 &&
diff -u file-fixed file
test_cmp file-fixed file
'
test_expect_success 'withfix (backward)' '
@@ -91,12 +91,12 @@ test_expect_success 'withfix (backward)' '
sed -e /h/d file-fixed >fixed-head &&
sed -e /h/d file >file-head &&
diff -u fixed-head file-head &&
test_cmp fixed-head file-head &&
sed -n -e /h/p file-fixed >fixed-tail &&
sed -n -e /h/p file >file-tail &&
! diff -u fixed-tail file-tail
! test_cmp fixed-tail file-tail
'

View File

@@ -22,14 +22,14 @@ test_expect_success 'am regularly from stdin' '
git checkout initial &&
git am <patchfile &&
git diff master >actual &&
diff -u expect actual
test_cmp expect actual
'
test_expect_success 'am regularly from file' '
git checkout initial &&
git am patchfile &&
git diff master >actual &&
diff -u expect actual
test_cmp expect actual
'
test_expect_success 'am regularly from stdin in subdirectory' '
@@ -41,7 +41,7 @@ test_expect_success 'am regularly from stdin in subdirectory' '
git am <../patchfile
) &&
git diff master>actual &&
diff -u expect actual
test_cmp expect actual
'
test_expect_success 'am regularly from file in subdirectory' '
@@ -53,7 +53,7 @@ test_expect_success 'am regularly from file in subdirectory' '
git am ../patchfile
) &&
git diff master >actual &&
diff -u expect actual
test_cmp expect actual
'
test_expect_success 'am regularly from file in subdirectory with full path' '
@@ -66,7 +66,7 @@ test_expect_success 'am regularly from file in subdirectory with full path' '
git am "$P/patchfile"
) &&
git diff master >actual &&
diff -u expect actual
test_cmp expect actual
'
test_done

View File

@@ -129,7 +129,7 @@ test_expect_success 'rerere kicked in' "! grep ======= a1"
test_expect_success 'rerere prefers first change' 'git diff a1 expect'
rm $rr/postimage
echo "$sha1 a1" | tr '\012' '\000' > .git/rr-cache/MERGE_RR
echo "$sha1 a1" | perl -pe 'y/\012/\000/' > .git/rr-cache/MERGE_RR
test_expect_success 'rerere clear' 'git rerere clear'

View File

@@ -45,6 +45,11 @@ A U Thor (5):
EOF
test_expect_success 'shortlog wrapping' 'diff -u expect out'
test_expect_success 'shortlog wrapping' 'test_cmp expect out'
git log HEAD > log
GIT_DIR=non-existing git shortlog -w < log > out
test_expect_success 'shortlog from non-git directory' 'test_cmp expect out'
test_done

View File

@@ -103,7 +103,7 @@ test_expect_success \
test_expect_success \
'[index v1] 2) create a stealth corruption in a delta base reference' \
'# this test assumes a delta smaller than 16 bytes at the end of the pack
git show-index <1.idx | sort -n | tail -n 1 | (
git show-index <1.idx | sort -n | sed -ne \$p | (
read delta_offs delta_sha1 &&
git cat-file blob "$delta_sha1" > blob_1 &&
chmod +w ".git/objects/pack/pack-${pack1}.pack" &&
@@ -141,7 +141,7 @@ test_expect_success \
test_expect_success \
'[index v2] 2) create a stealth corruption in a delta base reference' \
'# this test assumes a delta smaller than 16 bytes at the end of the pack
git show-index <1.idx | sort -n | tail -n 1 | (
git show-index <1.idx | sort -n | sed -ne \$p | (
read delta_offs delta_sha1 delta_crc &&
git cat-file blob "$delta_sha1" > blob_3 &&
chmod +w ".git/objects/pack/pack-${pack1}.pack" &&

View File

@@ -29,4 +29,53 @@ test_expect_success 'prune stale packs' '
'
test_expect_success 'prune --expire' '
before=$(git count-objects | sed "s/ .*//") &&
BLOB=$(echo aleph | git hash-object -w --stdin) &&
BLOB_FILE=.git/objects/$(echo $BLOB | sed "s/^../&\//") &&
test $((1 + $before)) = $(git count-objects | sed "s/ .*//") &&
test -f $BLOB_FILE &&
git prune --expire=1.hour.ago &&
test $((1 + $before)) = $(git count-objects | sed "s/ .*//") &&
test -f $BLOB_FILE &&
test-chmtime -86500 $BLOB_FILE &&
git prune --expire 1.day &&
test $before = $(git count-objects | sed "s/ .*//") &&
! test -f $BLOB_FILE
'
test_expect_success 'gc: implicit prune --expire' '
before=$(git count-objects | sed "s/ .*//") &&
BLOB=$(echo aleph_0 | git hash-object -w --stdin) &&
BLOB_FILE=.git/objects/$(echo $BLOB | sed "s/^../&\//") &&
test $((1 + $before)) = $(git count-objects | sed "s/ .*//") &&
test -f $BLOB_FILE &&
test-chmtime -$((86400*14-30)) $BLOB_FILE &&
git gc &&
test $((1 + $before)) = $(git count-objects | sed "s/ .*//") &&
test -f $BLOB_FILE &&
test-chmtime -$((86400*14+1)) $BLOB_FILE &&
git gc &&
test $before = $(git count-objects | sed "s/ .*//") &&
! test -f $BLOB_FILE
'
test_expect_success 'gc: refuse to start with invalid gc.pruneExpire' '
git config gc.pruneExpire invalid &&
test_must_fail git gc
'
test_expect_success 'gc: start with ok gc.pruneExpire' '
git config gc.pruneExpire 2.days.ago &&
git gc
'
test_done

View File

@@ -120,7 +120,7 @@ test_expect_success \
cd .. &&
git-clone parent child && cd child && git-push --all &&
cd ../parent &&
git-branch -a >branches && ! grep -q origin/master branches
git-branch -a >branches && ! grep origin/master branches
'
rewound_push_setup() {

View File

@@ -24,7 +24,7 @@ setup_repository () {
tokens_match () {
echo "$1" | tr ' ' '\012' | sort | sed -e '/^$/d' >expect &&
echo "$2" | tr ' ' '\012' | sort | sed -e '/^$/d' >actual &&
diff -u expect actual
test_cmp expect actual
}
check_remote_track () {
@@ -73,7 +73,7 @@ test_expect_success 'add another remote' '
sed -e "/^refs\/remotes\/origin\//d" \
-e "/^refs\/remotes\/second\//d" >actual &&
>expect &&
diff -u expect actual
test_cmp expect actual
)
'
@@ -93,7 +93,7 @@ test_expect_success 'remove remote' '
git for-each-ref "--format=%(refname)" refs/remotes |
sed -e "/^refs\/remotes\/origin\//d" >actual &&
>expect &&
diff -u expect actual
test_cmp expect actual
)
'

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