* whitespace=!indent,trail,space
-*.[ch] whitespace
+*.[ch] whitespace=indent,trail,space
--- /dev/null
+GIT v1.6.3.3 Release Notes
+==========================
+
+Fixes since v1.6.3.2
+--------------------
+
+ * "git archive" running on Cygwin can get stuck in an infinite loop.
+
+ * "git daemon" did not correctly parse the initial line that carries
+ virtual host request information.
+
+ * "git diff --textconv" leaked memory badly when the textconv filter
+ errored out.
+
+ * The built-in regular expressions to pick function names to put on
+ hunk header lines for java and objc were very inefficiently written.
+
+ * in certain error situations git-fetch (and git-clone) on Windows didn't
+ detect connection abort and ended up waiting indefinitely.
+
+ * import-tars script (in contrib) did not import symbolic links correctly.
+
+ * http.c used CURLOPT_SSLKEY even on libcURL version 7.9.2, even though
+ it was only available starting 7.9.3.
+
+ * low-level filelevel merge driver used return value from strdup()
+ without checking if we ran out of memory.
+
+ * "git rebase -i" left stray closing parenthesis in its reflog message.
+
+ * "git remote show" did not show all the URLs associated with the named
+ remote, even though "git remote -v" did. Made them consistent by
+ making the former show all URLs.
+
+ * "whitespace" attribute that is set was meant to detect all errors known
+ to git, but it told git to ignore trailing carriage-returns.
+
+Includes other documentation fixes.
startsb=[
endsb=]
tilde=~
+backtick=`
ifdef::backend-docbook[]
[linkgit-inlinemacro]
The URL of a remote repository. See linkgit:git-fetch[1] or
linkgit:git-push[1].
+remote.<name>.pushurl::
+ The push URL of a remote repository. See linkgit:git-push[1].
+
remote.<name>.proxy::
For remotes that require curl (http, https and ftp), the URL to
the proxy to use for that remote. Set to the empty string to
-u::
Update affected files from CVS repository before attempting export.
+-k::
+ Reverse CVS keyword expansion (e.g. $Revision: 1.2.3.4$
+ becomes $Revision$) in working CVS checkout before applying patch.
+
-w::
Specify the location of the CVS checkout to use for the export. This
option does not require GIT_DIR to be set before execution if the
$GIT_DIR/branches/ and configuration variables that are related
to fetching, pulling and pushing.
-The primary entry points are:
-
-get_remote_refs_for_fetch::
- Given the list of user-supplied `<repo> <refspec>...`,
- return the list of refs to fetch after canonicalizing
- them into `$GIT_DIR` relative paths
- (e.g. `refs/heads/foo`). When `<refspec>...` is empty
- the returned list of refs consists of the defaults
- for the given `<repo>`, if specified in
- `$GIT_DIR/remotes/`, `$GIT_DIR/branches/`, or `remote.*.fetch`
- configuration.
-
-get_remote_refs_for_push::
- Given the list of user-supplied `<repo> <refspec>...`,
- return the list of refs to push in a form suitable to be
- fed to the 'git-send-pack' command. When `<refspec>...`
- is empty the returned list of refs consists of the
- defaults for the given `<repo>`, if specified in
- `$GIT_DIR/remotes/`.
-
Author
------
Written by Junio C Hamano.
- 'self' will avoid including the sender
- 'cc' will avoid including anyone mentioned in Cc lines in the patch header
except for self (use 'self' for that).
-- 'ccbody' will avoid including anyone mentioned in Cc lines in the
+- 'bodycc' will avoid including anyone mentioned in Cc lines in the
patch body (commit message) except for self (use 'self' for that).
- 'sob' will avoid including anyone mentioned in Signed-off-by lines except
for self (use 'self' for that).
- 'cccmd' will avoid running the --cc-cmd.
-- 'body' is equivalent to 'sob' + 'ccbody'
+- 'body' is equivalent to 'sob' + 'bodycc'
- 'all' will suppress all auto cc values.
--
+
refs from stdin that don't exist in the local repository.
Use of this utility is encouraged in favor of directly accessing files under
-in the `.git` directory.
+the `.git` directory.
OPTIONS
-------
-s::
--hash::
- Only show the SHA1 hash, not the reference name. When also using
+ Only show the SHA1 hash, not the reference name. When combined with
--dereference the dereferenced tag will still be shown after the SHA1.
--verify::
update::
Update the registered submodules, i.e. clone missing submodules and
checkout the commit specified in the index of the containing repository.
- This will make the submodules HEAD be detached unless '--rebase' is
- specified or the key `submodule.$name.update` is set to `rebase`.
+ This will make the submodules HEAD be detached unless '--rebase' or
+ '--merge' is specified or the key `submodule.$name.update` is set to
+ `rebase` or `merge`.
+
If the submodule is not yet initialized, and you just want to use the
setting as stored in .gitmodules, you can automatically initialize the
the processing to terminate. This can be overridden by adding '|| :'
to the end of the command.
+
-As an example, "git submodule foreach 'echo $path `git rev-parse HEAD`' will
-show the path and currently checked out commit for each submodule.
+As an example, +git submodule foreach \'echo $path {backtick}git
+rev-parse HEAD{backtick}'+ will show the path and currently checked out
+commit for each submodule.
sync::
Synchronizes submodules' remote URL configuration setting
This option is only valid for the update command.
Don't fetch new objects from the remote site.
+--merge::
+ This option is only valid for the update command.
+ Merge the commit recorded in the superproject into the current branch
+ of the submodule. If this option is given, the submodule's HEAD will
+ not be detached. If a merge failure prevents this process, you will
+ have to resolve the resulting conflicts within the submodule with the
+ usual conflict resolution tools.
+ If the key `submodule.$name.update` is set to `merge`, this option is
+ implicit.
+
--rebase::
This option is only valid for the update command.
Rebase the current branch onto the commit recorded in the
NAME
----
-git-svn - Bidirectional operation between a single Subversion branch and git
+git-svn - Bidirectional operation between a Subversion repository and git
SYNOPSIS
--------
It provides a bidirectional flow of changes between a Subversion and a git
repository.
-'git-svn' can track a single Subversion branch simply by using a
-URL to the branch, follow branches laid out in the Subversion recommended
-method (trunk, branches, tags directories) with the --stdlayout option, or
-follow branches in any layout with the -T/-t/-b options (see options to
-'init' below, and also the 'clone' command).
+'git-svn' can track a standard Subversion repository,
+following the common "trunk/branches/tags" layout, with the --stdlayout option.
+It can also follow branches and tags in any layout with the -T/-t/-b options
+(see options to 'init' below, and also the 'clone' command).
-Once tracking a Subversion branch (with any of the above methods), the git
+Once tracking a Subversion repository (with any of the above methods), the git
repository can be updated from Subversion by the 'fetch' command and
Subversion updated from git by the 'dcommit' command.
--stdlayout;;
These are optional command-line options for init. Each of
these flags can point to a relative repository path
- (--tags=project/tags') or a full url
- (--tags=https://foo.org/project/tags). The option --stdlayout is
+ (--tags=project/tags) or a full url
+ (--tags=https://foo.org/project/tags).
+ You can specify more than one --tags and/or --branches options, in case
+ your Subversion repository places tags or branches under multiple paths.
+ The option --stdlayout is
a shorthand way of setting trunk,tags,branches as the relative paths,
which is the Subversion default. If any of the other options are given
as well, they take precedence.
It is recommended that you run 'git-svn' fetch and rebase (not
pull or merge) your commits against the latest changes in the
SVN repository.
- An optional command-line argument may be specified as an
- alternative to HEAD.
+ An optional revision or branch argument may be specified, and
+ causes 'git-svn' to do all work on that revision/branch
+ instead of HEAD.
This is advantageous over 'set-tree' (below) because it produces
cleaner, more linear history.
+
Create a tag by using the tags_subdir instead of the branches_subdir
specified during git svn init.
+-d;;
+--destination;;
+ If more than one --branches (or --tags) option was given to the 'init'
+ or 'clone' command, you must provide the location of the branch (or
+ tag) you wish to create in the SVN repository. The value of this
+ option must match one of the paths specified by a --branches (or
+ --tags) option. You can see these paths with the commands
++
+ git config --get-all svn-remote.<name>.branches
+ git config --get-all svn-remote.<name>.tags
++
+where <name> is the name of the SVN repository as specified by the -R option to
+'init' (or "svn" by default).
+
'tag'::
Create a tag in the SVN repository. This is a shorthand for
'branch -t'.
The following features from `svn log' are supported:
+
--
---revision=<n>[:<n>];;
+-r/--revision=<n>[:<n>];;
is supported, non-numeric args are not:
HEAD, NEXT, BASE, PREV, etc ...
-v/--verbose;;
Shows the Subversion externals. Use -r/--revision to specify a
specific revision.
+'reset'::
+ Undoes the effects of 'fetch' back to the specified revision.
+ This allows you to re-'fetch' an SVN revision. Normally the
+ contents of an SVN revision should never change and 'reset'
+ should not be necessary. However, if SVN permissions change,
+ or if you alter your --ignore-paths option, a 'fetch' may fail
+ with "not found in commit" (file not previously visible) or
+ "checksum mismatch" (missed a modification). If the problem
+ file cannot be ignored forever (with --ignore-paths) the only
+ way to repair the repo is to use 'reset'.
+
+Only the rev_map and refs/remotes/git-svn are changed. Follow 'reset'
+with a 'fetch' and then 'git-reset' or 'git-rebase' to move local
+branches onto the new tree.
+
+-r/--revision=<n>;;
+ Specify the most recent revision to keep. All later revisions
+ are discarded.
+-p/--parent;;
+ Discard the specified revision as well, keeping the nearest
+ parent instead.
+Example:;;
+Assume you have local changes in "master", but you need to refetch "r2".
+
+------------
+ r1---r2---r3 remotes/git-svn
+ \
+ A---B master
+------------
+
+Fix the ignore-paths or SVN permissions problem that caused "r2" to
+be incomplete in the first place. Then:
+
+[verse]
+git svn reset -r2 -p
+git svn fetch
+
+------------
+ r1---r2'--r3' remotes/git-svn
+ \
+ r2---r3---A---B master
+------------
+
+Then fixup "master" with 'git-rebase'.
+Do NOT use 'git-merge' or your history will not be compatible with a
+future 'dcommit'!
+
+[verse]
+git rebase --onto remotes/git-svn A^ master
+
+------------
+ r1---r2'--r3' remotes/git-svn
+ \
+ A'--B' master
+------------
+
+
--
OPTIONS
If you use `git svn set-tree A..B` to commit several diffs and you do
not have the latest remotes/git-svn merged into my-branch, you should
use `git svn rebase` to update your work branch instead of `git pull` or
-`git merge`. `pull`/`merge' can cause non-linear history to be flattened
+`git merge`. `pull`/`merge` can cause non-linear history to be flattened
when committing into SVN, which can lead to merge commits reversing
previous commits in SVN.
you've already pushed to a remote repository for other users, and
dcommit with SVN is analogous to that.
+When using multiple --branches or --tags, 'git-svn' does not automatically
+handle name collisions (for example, if two branches from different paths have
+the same name, or if a branch and a tag have the same name). In these cases,
+use 'init' to set up your git repository then, before your first 'fetch', edit
+the .git/config file so that the branches and tags are associated with
+different name spaces. For example:
+
+ branches = stable/*:refs/remotes/svn/stable/*
+ branches = debug/*:refs/remotes/svn/debug/*
+
BUGS
----
branch of the `git.git` repository.
Documentation for older releases are available here:
-* link:v1.6.3.2/git.html[documentation for release 1.6.3.2]
+* link:v1.6.3.3/git.html[documentation for release 1.6.3.3]
* release notes for
+ link:RelNotes-1.6.3.3.txt[1.6.3.3],
link:RelNotes-1.6.3.2.txt[1.6.3.2],
link:RelNotes-1.6.3.1.txt[1.6.3.1],
link:RelNotes-1.6.3.txt[1.6.3].
If 'checkout' (the default), the new commit specified in the
superproject will be checked out in the submodule on a detached HEAD.
If 'rebase', the current branch of the submodule will be rebased onto
- the commit specified in the superproject.
+ the commit specified in the superproject. If 'merge', the commit
+ specified in the superproject will be merged into the current branch
+ in the submodule.
This config option is overridden if 'git submodule update' is given
- the '--rebase' option.
+ the '--merge' or '--rebase' options.
EXAMPLES
------------------------------------------------
This operation is safe even if Alice has uncommitted local changes.
-The range notation HEAD..FETCH_HEAD" means "show everything that is reachable
-from the FETCH_HEAD but exclude anything that is reachable from HEAD.
+The range notation "HEAD..FETCH_HEAD" means "show everything that is reachable
+from the FETCH_HEAD but exclude anything that is reachable from HEAD".
Alice already knows everything that leads to her current state (HEAD),
-and reviewing what Bob has in his state (FETCH_HEAD) that she has not
-seen with this command
+and reviews what Bob has in his state (FETCH_HEAD) that she has not
+seen with this command.
If Alice wants to visualize what Bob did since their histories forked
she can issue the following command:
alice$ git remote add bob /home/bob/myrepo
------------------------------------------------
-With this, Alice can perform the first part of the "pull" operation alone using the
-'git-fetch' command without merging them with her own branch,
-using:
+With this, Alice can perform the first part of the "pull" operation
+alone using the 'git-fetch' command without merging them with her own
+branch, using:
-------------------------------------
alice$ git fetch bob
You can also give 'git-log' a "range" of commits where the first is not
necessarily an ancestor of the second; for example, if the tips of
-the branches "stable-release" and "master" diverged from a common
+the branches "stable" and "master" diverged from a common
commit some time ago, then
-------------------------------------
-$ git log stable..experimental
+$ git log stable..master
-------------------------------------
-will list commits made in the experimental branch but not in the
+will list commits made in the master branch but not in the
stable branch, while
-------------------------------------
-$ git log experimental..stable
+$ git log master..stable
-------------------------------------
will show the list of commits made on the stable branch but not
-the experimental branch.
+the master branch.
The 'git-log' command has a weakness: it must present commits in a
list. When the history has lines of development that diverged and
An array of all of the url_nr URLs configured for the remote
+`pushurl`::
+
+ An array of all of the pushurl_nr push URLs configured for the remote
+
`push`::
An array of refspecs configured for pushing, with
------------
[remote "<name>"]
url = <url>
+ pushurl = <pushurl>
push = <refspec>
fetch = <refspec>
------------
+The `<pushurl>` is used for pushes only. It is optional and defaults
+to `<url>`.
Named file in `$GIT_DIR/remotes`
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
$(LIBS) $(CURL_LIBCURL) $(EXPAT_LIBEXPAT)
$(LIB_OBJS) $(BUILTIN_OBJS): $(LIB_H)
-$(patsubst git-%$X,%.o,$(PROGRAMS)): $(LIB_H) $(wildcard */*.h)
+$(patsubst git-%$X,%.o,$(PROGRAMS)) git.o: $(LIB_H) $(wildcard */*.h)
builtin-revert.o wt-status.o: wt-status.h
$(LIB_FILE): $(LIB_OBJS)
static unsigned hash_name(const char *name, int namelen)
{
- unsigned val = 0;
- unsigned char c;
+ unsigned val = 0, c;
while (namelen--) {
c = *name++;
}
}
+ strbuf_release(&pathbuf);
+
/*
* Finally push the "info" one at the top of the stack.
*/
unsigned acc = 0;
int cnt;
for (cnt = 24; cnt >= 0; cnt -= 8) {
- int ch = *data++;
+ unsigned ch = *data++;
acc |= ch << cnt;
if (--bytes == 0)
break;
return for_each_ref_in("refs/bisect/", register_ref, NULL);
}
-void read_bisect_paths(struct argv_array *array)
+static void read_bisect_paths(struct argv_array *array)
{
struct strbuf str = STRBUF_INIT;
const char *filename = git_path("BISECT_NAMES");
exit(1);
}
-void handle_skipped_merge_base(const unsigned char *mb)
+static void handle_skipped_merge_base(const unsigned char *mb)
{
char *mb_hex = sha1_to_hex(mb);
char *bad_hex = sha1_to_hex(current_bad_sha1);
return status;
}
-int edit_patch(int argc, const char **argv, const char *prefix)
+static int edit_patch(int argc, const char **argv, const char *prefix)
{
char *file = xstrdup(git_path("ADD_EDIT.patch"));
const char *apply_argv[] = { "apply", "--recount", "--cached",
int add_new_files;
int require_pathspec;
+ git_config(add_config, NULL);
+
argc = parse_options(argc, argv, prefix, builtin_add_options,
builtin_add_usage, PARSE_OPT_KEEP_ARGV0);
if (patch_interactive)
if (add_interactive)
exit(interactive_add(argc - 1, argv + 1, prefix));
- git_config(add_config, NULL);
-
if (edit_interactive)
return(edit_patch(argc, argv, prefix));
argc--;
static void build_fake_ancestor(struct patch *list, const char *filename)
{
struct patch *patch;
- struct index_state result = { 0 };
+ struct index_state result = { NULL };
int fd;
/* Once we start supporting the reverse patch, it may be
OPT_BOOLEAN(0, "stat", &diffstat,
"instead of applying the patch, output diffstat for the input"),
{ OPTION_BOOLEAN, 0, "allow-binary-replacement", &binary,
- NULL, "old option, now no-op", PARSE_OPT_HIDDEN },
+ NULL, "old option, now no-op",
+ PARSE_OPT_HIDDEN | PARSE_OPT_NOARG },
{ OPTION_BOOLEAN, 0, "binary", &binary,
- NULL, "old option, now no-op", PARSE_OPT_HIDDEN },
+ NULL, "old option, now no-op",
+ PARSE_OPT_HIDDEN | PARSE_OPT_NOARG },
OPT_BOOLEAN(0, "numstat", &numstat,
"shows number of added and deleted lines in decimal notation"),
OPT_BOOLEAN(0, "summary", &summary,
if (is_bare) {
struct strbuf result = STRBUF_INIT;
strbuf_addf(&result, "%.*s.git", (int)(end - start), start);
- dir = strbuf_detach(&result, 0);
+ dir = strbuf_detach(&result, NULL);
} else
dir = xstrndup(start, end - start);
/*
ref->value = xcalloc(sizeof(struct atom_value), used_atom_cnt);
- buf = get_obj(ref->objectname, &obj, &size, &eaten);
- if (!buf)
- die("missing object %s for %s",
- sha1_to_hex(ref->objectname), ref->refname);
- if (!obj)
- die("parse_object_buffer failed on %s for %s",
- sha1_to_hex(ref->objectname), ref->refname);
-
/* Fill in specials first */
for (i = 0; i < used_atom_cnt; i++) {
const char *name = used_atom[i];
}
}
+ for (i = 0; i < used_atom_cnt; i++) {
+ struct atom_value *v = &ref->value[i];
+ if (v->s == NULL)
+ goto need_obj;
+ }
+ return;
+
+ need_obj:
+ buf = get_obj(ref->objectname, &obj, &size, &eaten);
+ if (!buf)
+ die("missing object %s for %s",
+ sha1_to_hex(ref->objectname), ref->refname);
+ if (!obj)
+ die("parse_object_buffer failed on %s for %s",
+ sha1_to_hex(ref->objectname), ref->refname);
+
grab_values(ref->value, 0, obj, buf, size);
if (!eaten)
free(buf);
memset(&cbdata, 0, sizeof(cbdata));
cbdata.grab_pattern = argv;
- for_each_ref(grab_single_ref, &cbdata);
+ for_each_rawref(grab_single_ref, &cbdata);
refs = cbdata.grab_array;
num_refs = cbdata.grab_cnt;
static void mark_object_reachable(struct object *obj)
{
- mark_object(obj, OBJ_ANY, 0);
+ mark_object(obj, OBJ_ANY, NULL);
}
static int traverse_one_object(struct object *obj, struct object *parent)
fprintf(stderr, "Checking %s %s\n",
typename(obj->type), sha1_to_hex(obj->sha1));
- if (fsck_walk(obj, mark_used, 0))
+ if (fsck_walk(obj, mark_used, NULL))
objerror(obj, "broken links");
if (fsck_object(obj, check_strict, fsck_error_func))
return -1;
* HTML.
*/
#ifndef open_html
-void open_html(const char *path)
+static void open_html(const char *path)
{
execl_git_cmd("web--browse", "-c", "help.browser", path, NULL);
}
printf("Final output: %d %s\n", nr, stage);
}
-struct itimerval early_output_timer;
+static struct itimerval early_output_timer;
static void log_show_early(struct rev_info *revs, struct commit_list *list)
{
strbuf_addch(&buf, '\n');
}
- rev.extra_headers = strbuf_detach(&buf, 0);
+ rev.extra_headers = strbuf_detach(&buf, NULL);
if (start_number < 0)
start_number = 1;
strbuf_addstr(&buf, "refs/heads/");
strbuf_addstr(&buf, remote);
- resolve_ref(buf.buf, branch_head, 0, 0);
+ resolve_ref(buf.buf, branch_head, 0, NULL);
if (!hashcmp(remote_head->sha1, branch_head)) {
strbuf_addf(msg, "%s\t\tbranch '%s' of .\n",
strbuf_addstr(&truname, "refs/heads/");
strbuf_addstr(&truname, remote);
strbuf_setlen(&truname, truname.len - len);
- if (resolve_ref(truname.buf, buf_sha, 0, 0)) {
+ if (resolve_ref(truname.buf, buf_sha, 0, NULL)) {
strbuf_addf(msg,
"%s\t\tbranch '%s'%s of .\n",
sha1_to_hex(remote_head->sha1),
result[count] = NULL;
for (i = 0; i < count; i++) {
int length = strlen(result[i]);
- if (length > 0 && result[i][length - 1] == '/') {
+ if (length > 0 && is_dir_sep(result[i][length - 1]))
result[i] = xmemdupz(result[i], length - 1);
- }
- if (base_name) {
- const char *last_slash = strrchr(result[i], '/');
- if (last_slash)
- result[i] = last_slash + 1;
- }
+ if (base_name)
+ result[i] = basename((char *)result[i]);
}
return get_pathspec(prefix, result);
}
static unsigned name_hash(const char *name)
{
- unsigned char c;
- unsigned hash = 0;
+ unsigned c, hash = 0;
if (!name)
return 0;
{
int i, errs;
struct remote *remote = remote_get(repo);
+ const char **url;
+ int url_nr;
if (!remote) {
if (repo)
setup_default_push_refspecs();
}
errs = 0;
- for (i = 0; i < remote->url_nr; i++) {
+ if (remote->pushurl_nr) {
+ url = remote->pushurl;
+ url_nr = remote->pushurl_nr;
+ } else {
+ url = remote->url;
+ url_nr = remote->url_nr;
+ }
+ for (i = 0; i < url_nr; i++) {
struct transport *transport =
- transport_get(remote, remote->url[i]);
+ transport_get(remote, url[i]);
int err;
if (receivepack)
transport_set_option(transport,
transport_set_option(transport, TRANS_OPT_THIN, "yes");
if (flags & TRANSPORT_PUSH_VERBOSE)
- fprintf(stderr, "Pushing to %s\n", remote->url[i]);
+ fprintf(stderr, "Pushing to %s\n", url[i]);
err = transport_push(transport, refspec_nr, refspec, flags);
err |= transport_disconnect(transport);
if (!err)
continue;
- error("failed to push some refs to '%s'", remote->url[i]);
+ error("failed to push some refs to '%s'", url[i]);
errs++;
}
return !!errs;
return result;
}
-void clear_push_info(void *util, const char *string)
+static void clear_push_info(void *util, const char *string)
{
struct push_info *info = util;
free(info->dest);
int any_rebase;
};
-int add_remote_to_show_info(struct string_list_item *item, void *cb_data)
+static int add_remote_to_show_info(struct string_list_item *item, void *cb_data)
{
struct show_info *info = cb_data;
int n = strlen(item->string);
return 0;
}
-int show_remote_info_item(struct string_list_item *item, void *cb_data)
+static int show_remote_info_item(struct string_list_item *item, void *cb_data)
{
struct show_info *info = cb_data;
struct ref_states *states = info->states;
return 0;
}
-int add_local_to_show_info(struct string_list_item *branch_item, void *cb_data)
+static int add_local_to_show_info(struct string_list_item *branch_item, void *cb_data)
{
struct show_info *show_info = cb_data;
struct ref_states *states = show_info->states;
return 0;
}
-int show_local_info_item(struct string_list_item *item, void *cb_data)
+static int show_local_info_item(struct string_list_item *item, void *cb_data)
{
struct show_info *show_info = cb_data;
struct branch_info *branch_info = item->util;
return 0;
}
-int add_push_to_show_info(struct string_list_item *push_item, void *cb_data)
+static int add_push_to_show_info(struct string_list_item *push_item, void *cb_data)
{
struct show_info *show_info = cb_data;
struct push_info *push_info = push_item->util;
return cmp ? cmp : strcmp(a_push->dest, b_push->dest);
}
-int show_push_info_item(struct string_list_item *item, void *cb_data)
+static int show_push_info_item(struct string_list_item *item, void *cb_data)
{
struct show_info *show_info = cb_data;
struct push_info *push_info = item->util;
info.list = &info_list;
for (; argc; argc--, argv++) {
int i;
+ const char **url;
+ int url_nr;
get_remote_ref_states(*argv, &states, query_flag);
printf("* remote %s\n", *argv);
- if (states.remote->url_nr) {
- for (i=0; i < states.remote->url_nr; i++)
- printf(" URL: %s\n", states.remote->url[i]);
- } else
- printf(" URL: %s\n", "(no URL)");
+ printf(" Fetch URL: %s\n", states.remote->url_nr > 0 ?
+ states.remote->url[0] : "(no URL)");
+ if (states.remote->pushurl_nr) {
+ url = states.remote->pushurl;
+ url_nr = states.remote->pushurl_nr;
+ } else {
+ url = states.remote->url;
+ url_nr = states.remote->url_nr;
+ }
+ for (i=0; i < url_nr; i++)
+ printf(" Push URL: %s\n", url[i]);
+ if (!i)
+ printf(" Push URL: %s\n", "(no URL)");
if (no_query)
printf(" HEAD branch: (not queried)\n");
else if (!states.heads.nr)
return 0;
}
-struct remote_group {
+static struct remote_group {
const char *name;
struct string_list *list;
} remote_group;
static int get_one_entry(struct remote *remote, void *priv)
{
struct string_list *list = priv;
+ struct strbuf url_buf = STRBUF_INIT;
+ const char **url;
+ int i, url_nr;
if (remote->url_nr > 0) {
- int i;
-
- for (i = 0; i < remote->url_nr; i++)
- string_list_append(remote->name, list)->util = (void *)remote->url[i];
+ strbuf_addf(&url_buf, "%s (fetch)", remote->url[0]);
+ string_list_append(remote->name, list)->util =
+ strbuf_detach(&url_buf, NULL);
} else
string_list_append(remote->name, list)->util = NULL;
+ if (remote->pushurl_nr) {
+ url = remote->pushurl;
+ url_nr = remote->pushurl_nr;
+ } else {
+ url = remote->url;
+ url_nr = remote->url_nr;
+ }
+ for (i = 0; i < url_nr; i++)
+ {
+ strbuf_addf(&url_buf, "%s (push)", url[i]);
+ string_list_append(remote->name, list)->util =
+ strbuf_detach(&url_buf, NULL);
+ }
return 0;
}
static int show_all(void)
{
struct string_list list = { NULL, 0, 0 };
- int result = for_each_remote(get_one_entry, &list);
+ int result;
+
+ list.strdup_strings = 1;
+ result = for_each_remote(get_one_entry, &list);
if (!result) {
int i;
}
}
}
+ string_list_clear(&list, 1);
return result;
}
struct commit_list *with_commit = NULL;
struct option options[] = {
OPT_BOOLEAN('l', NULL, &list, "list tag names"),
- { OPTION_INTEGER, 'n', NULL, &lines, NULL,
- "print n lines of each tag message",
+ { OPTION_INTEGER, 'n', NULL, &lines, "n",
+ "print <n> lines of each tag message",
PARSE_OPT_OPTARG, NULL, 1 },
OPT_BOOLEAN('d', NULL, &delete, "delete tags"),
OPT_BOOLEAN('v', NULL, &verify, "verify tags"),
#define FLAG_WRITTEN (1u<<21)
static struct obj_info *obj_list;
-unsigned nr_objects;
+static unsigned nr_objects;
/*
* Called only from check_object() after it verified this object
if (fsck_object(obj, 1, fsck_error_function))
die("Error in object");
- if (!fsck_walk(obj, check_object, 0))
+ if (!fsck_walk(obj, check_object, NULL))
die("Error on reachable objects of %s", sha1_to_hex(obj->sha1));
write_cached_object(obj);
return 1;
{
unsigned i;
for (i = 0; i < nr_objects; i++)
- check_object(obj_list[i].obj, OBJ_ANY, 0);
+ check_object(obj_list[i].obj, OBJ_ANY, NULL);
}
static void added_object(unsigned nr, enum object_type type,
static void unpack_one(unsigned nr)
{
unsigned shift;
- unsigned char *pack, c;
- unsigned long size;
+ unsigned char *pack;
+ unsigned long size, c;
enum object_type type;
obj_list[nr].offset = consumed_bytes;
die("sent error to the client: %s", buf);
}
-static void process_input(int child_fd, int band)
+static ssize_t process_input(int child_fd, int band)
{
char buf[16384];
ssize_t sz = read(child_fd, buf, sizeof(buf));
if (sz < 0) {
if (errno != EAGAIN && errno != EINTR)
error_clnt("read error: %s\n", strerror(errno));
- return;
+ return sz;
}
send_sideband(1, band, buf, sz, LARGE_PACKET_MAX);
+ return sz;
}
int cmd_upload_archive(int argc, const char **argv, const char *prefix)
while (1) {
struct pollfd pfd[2];
+ ssize_t processed[2] = { 0, 0 };
int status;
pfd[0].fd = fd1[0];
}
if (pfd[0].revents & POLLIN)
/* Data stream ready */
- process_input(pfd[0].fd, 1);
+ processed[0] = process_input(pfd[0].fd, 1);
if (pfd[1].revents & POLLIN)
/* Status stream ready */
- process_input(pfd[1].fd, 2);
+ processed[1] = process_input(pfd[1].fd, 2);
/* Always finish to read data when available */
- if ((pfd[0].revents | pfd[1].revents) & POLLIN)
+ if (processed[0] || processed[1])
continue;
if (waitpid(writer, &status, 0) < 0)
int cmd_write_tree(int argc, const char **argv, const char *unused_prefix)
{
- int missing_ok = 0, ret;
+ int flags = 0, ret;
const char *prefix = NULL;
unsigned char sha1[20];
const char *me = "git-write-tree";
while (1 < argc) {
const char *arg = argv[1];
if (!strcmp(arg, "--missing-ok"))
- missing_ok = 1;
+ flags |= WRITE_TREE_MISSING_OK;
else if (!prefixcmp(arg, "--prefix="))
prefix = arg + 9;
+ else if (!prefixcmp(arg, "--ignore-cache-tree"))
+ /*
+ * This is only useful for debugging, so I
+ * do not bother documenting it.
+ */
+ flags |= WRITE_TREE_IGNORE_CACHE_TREE;
else
usage(write_tree_usage);
argc--; argv++;
if (argc > 2)
die("too many options");
- ret = write_cache_as_tree(sha1, missing_ok, prefix);
+ ret = write_cache_as_tree(sha1, flags, prefix);
switch (ret) {
case 0:
printf("%s\n", sha1_to_hex(sha1));
static struct cache_tree *cache_tree_find(struct cache_tree *it, const char *path)
{
+ if (!it)
+ return NULL;
while (*path) {
const char *slash;
struct cache_tree_sub *sub;
return it;
}
-int write_cache_as_tree(unsigned char *sha1, int missing_ok, const char *prefix)
+int write_cache_as_tree(unsigned char *sha1, int flags, const char *prefix)
{
int entries, was_valid, newfd;
+ struct lock_file *lock_file;
/*
* We can't free this memory, it becomes part of a linked list
* parsed atexit()
*/
- struct lock_file *lock_file = xcalloc(1, sizeof(struct lock_file));
+ lock_file = xcalloc(1, sizeof(struct lock_file));
newfd = hold_locked_index(lock_file, 1);
entries = read_cache();
if (entries < 0)
return WRITE_TREE_UNREADABLE_INDEX;
+ if (flags & WRITE_TREE_IGNORE_CACHE_TREE)
+ cache_tree_free(&(active_cache_tree));
if (!active_cache_tree)
active_cache_tree = cache_tree();
was_valid = cache_tree_fully_valid(active_cache_tree);
-
if (!was_valid) {
+ int missing_ok = flags & WRITE_TREE_MISSING_OK;
+
if (cache_tree_update(active_cache_tree,
active_cache, active_nr,
missing_ok, 0) < 0)
*it = cache_tree();
prime_cache_tree_rec(*it, tree);
}
+
+/*
+ * find the cache_tree that corresponds to the current level without
+ * exploding the full path into textual form. The root of the
+ * cache tree is given as "root", and our current level is "info".
+ * (1) When at root level, info->prev is NULL, so it is "root" itself.
+ * (2) Otherwise, find the cache_tree that corresponds to one level
+ * above us, and find ourselves in there.
+ */
+static struct cache_tree *find_cache_tree_from_traversal(struct cache_tree *root,
+ struct traverse_info *info)
+{
+ struct cache_tree *our_parent;
+
+ if (!info->prev)
+ return root;
+ our_parent = find_cache_tree_from_traversal(root, info->prev);
+ return cache_tree_find(our_parent, info->name.path);
+}
+
+int cache_tree_matches_traversal(struct cache_tree *root,
+ struct name_entry *ent,
+ struct traverse_info *info)
+{
+ struct cache_tree *it;
+
+ it = find_cache_tree_from_traversal(root, info);
+ it = cache_tree_find(it, ent->path);
+ if (it && it->entry_count > 0 && !hashcmp(ent->sha1, it->sha1))
+ return it->entry_count;
+ return 0;
+}
#define CACHE_TREE_H
#include "tree.h"
+#include "tree-walk.h"
struct cache_tree;
struct cache_tree_sub {
int cache_tree_fully_valid(struct cache_tree *);
int cache_tree_update(struct cache_tree *, struct cache_entry **, int, int, int);
+/* bitmasks to write_cache_as_tree flags */
+#define WRITE_TREE_MISSING_OK 1
+#define WRITE_TREE_IGNORE_CACHE_TREE 2
+
+/* error return codes */
#define WRITE_TREE_UNREADABLE_INDEX (-1)
#define WRITE_TREE_UNMERGED_INDEX (-2)
#define WRITE_TREE_PREFIX_ERROR (-3)
-int write_cache_as_tree(unsigned char *sha1, int missing_ok, const char *prefix);
+int write_cache_as_tree(unsigned char *sha1, int flags, const char *prefix);
void prime_cache_tree(struct cache_tree **, struct tree *);
+extern int cache_tree_matches_traversal(struct cache_tree *, struct name_entry *ent, struct traverse_info *info);
+
#endif
# some Solaris installations).
# Define NO_ICONV if neither libc nor libiconv support iconv.
+if test -z "$NO_ICONV"; then
+
GIT_STASH_FLAGS($ICONVDIR)
AC_DEFUN([ICONVTEST_SRC], [
AC_SUBST(NEEDS_LIBICONV)
AC_SUBST(NO_ICONV)
+if test -n "$NO_ICONV"; then
+ NEEDS_LIBICONV=
+fi
+
+fi
+
#
# Define NO_DEFLATE_BOUND if deflateBound is missing from zlib.
#define MAX_CMD_LEN 1024
-char *get_port(char *host)
+static char *get_port(char *host)
{
char *end;
char *p = strchr(host, ':');
}
__git_send_email_confirm_options="always never auto cc compose"
-__git_send_email_suppresscc_options="author self cc ccbody sob cccmd body all"
+__git_send_email_suppresscc_options="author self cc bodycc sob cccmd body all"
_git_send_email ()
{
branch.*.*)
local pfx="${cur%.*}."
cur="${cur##*.}"
- __gitcomp "remote merge mergeoptions" "$pfx" "$cur"
+ __gitcomp "remote merge mergeoptions rebase" "$pfx" "$cur"
return
;;
branch.*)
cur="${cur##*.}"
__gitcomp "
url proxy fetch push mirror skipDefaultUpdate
- receivepack uploadpack tagopt
+ receivepack uploadpack tagopt pushurl
" "$pfx" "$cur"
return
;;
;;
esac
__gitcomp "
+ add.ignore-errors
alias.
apply.whitespace
branch.autosetupmerge
$mtime = oct $mtime;
next if $typeflag == 5; # directory
- print FI "blob\n", "mark :$next_mark\n", "data $size\n";
- while ($size > 0 && read(I, $_, 512) == 512) {
- print FI substr($_, 0, $size);
- $size -= 512;
+ print FI "blob\n", "mark :$next_mark\n";
+ if ($typeflag == 2) { # symbolic link
+ print FI "data ", length($linkname), "\n", $linkname;
+ $mode = 0120000;
+ } else {
+ print FI "data $size\n";
+ while ($size > 0 && read(I, $_, 512) == 512) {
+ print FI substr($_, 0, $size);
+ $size -= 512;
+ }
}
print FI "\n";
{
my ($mark, $mode) = @{$files{$path}};
$path =~ s,^([^/]+)/,, if $have_top_dir;
- printf FI "M %o :%i %s\n", $mode & 0111 ? 0755 : 0644, $mark, $path;
+ $mode = $mode & 0111 ? 0755 : 0644 unless $mode == 0120000;
+ printf FI "M %o :%i %s\n", $mode, $mark, $path;
}
print FI "\n";
memset(&hints, 0, sizeof(hints));
hints.ai_flags = AI_CANONNAME;
- gai = getaddrinfo(hostname, 0, &hints, &ai);
+ gai = getaddrinfo(hostname, NULL, &hints, &ai);
if (!gai) {
struct sockaddr_in *sin_addr = (void *)ai->ai_addr;
const unsigned char *top)
{
const unsigned char *data = *datap;
- unsigned char cmd;
- unsigned long size = 0;
+ unsigned long cmd, size = 0;
int i = 0;
do {
cmd = *data++;
- size |= (cmd & ~0x80) << i;
+ size |= (cmd & 0x7f) << i;
i += 7;
} while (cmd & 0x80 && data < top);
*datap = data;
memset(&opts, 0, sizeof(opts));
opts.head_idx = 1;
opts.index_only = cached;
+ opts.diff_index_cached = (cached &&
+ !DIFF_OPT_TST(&revs->diffopt, FIND_COPIES_HARDER));
opts.merge = 1;
opts.fn = oneway_diff;
opts.unpack_data = revs;
memset(&opts, 0, sizeof(opts));
opts.head_idx = 1;
opts.index_only = 1;
+ opts.diff_index_cached = !DIFF_OPT_TST(opt, FIND_COPIES_HARDER);
opts.merge = 1;
opts.fn = oneway_diff;
opts.unpack_data = &revs;
use File::Spec;
use Git;
-our ($opt_h, $opt_P, $opt_p, $opt_v, $opt_c, $opt_f, $opt_a, $opt_m, $opt_d, $opt_u, $opt_w, $opt_W);
+our ($opt_h, $opt_P, $opt_p, $opt_v, $opt_c, $opt_f, $opt_a, $opt_m, $opt_d, $opt_u, $opt_w, $opt_W, $opt_k);
-getopts('uhPpvcfam:d:w:W');
+getopts('uhPpvcfkam:d:w:W');
$opt_h && usage();
$dirty = 1;
warn "File $f not up to date but has status '$cvsstat{$f}' in your CVS checkout!\n";
}
+
+ # Depending on how your GIT tree got imported from CVS you may
+ # have a conflict between expanded keywords in your CVS tree and
+ # unexpanded keywords in the patch about to be applied.
+ if ($opt_k) {
+ my $orig_file ="$f.orig";
+ rename $f, $orig_file;
+ open(FILTER_IN, "<$orig_file") or die "Cannot open $orig_file\n";
+ open(FILTER_OUT, ">$f") or die "Cannot open $f\n";
+ while (<FILTER_IN>)
+ {
+ my $line = $_;
+ $line =~ s/\$([A-Z][a-z]+):[^\$]+\$/\$\1\$/g;
+ print FILTER_OUT $line;
+ }
+ close FILTER_IN;
+ close FILTER_OUT;
+ }
}
+
if ($dirty) {
if ($opt_f) { warn "The tree is not clean -- forced merge\n";
$dirty = 0;
sub usage {
print STDERR <<END;
-Usage: GIT_DIR=/path/to/.git git cvsexportcommit [-h] [-p] [-v] [-c] [-f] [-u] [-w cvsworkdir] [-m msgprefix] [ parent ] commit
+Usage: GIT_DIR=/path/to/.git git cvsexportcommit [-h] [-p] [-v] [-c] [-f] [-u] [-k] [-w cvsworkdir] [-m msgprefix] [ parent ] commit
END
exit(1);
}
echo ${origin:-origin}
}
-get_remote_default_refs_for_push () {
- data_source=$(get_data_source "$1")
- case "$data_source" in
- '' | branches | self)
- ;; # no default push mapping, just send matching refs.
- config)
- git config --get-all "remote.$1.push" ;;
- remotes)
- sed -ne '/^Push: */{
- s///p
- }' "$GIT_DIR/remotes/$1" ;;
- *)
- die "internal error: get-remote-default-ref-for-push $1" ;;
- esac
-}
-
-# Called from canon_refs_list_for_fetch -d "$remote", which
-# is called from get_remote_default_refs_for_fetch to grok
-# refspecs that are retrieved from the configuration, but not
-# from get_remote_refs_for_fetch when it deals with refspecs
-# supplied on the command line. $ls_remote_result has the list
-# of refs available at remote.
-#
-# The first token returned is either "explicit" or "glob"; this
-# is to help prevent randomly "globbed" ref from being chosen as
-# a merge candidate
-expand_refs_wildcard () {
- echo "$ls_remote_result" |
- git fetch--tool expand-refs-wildcard "-" "$@"
-}
-
-# Subroutine to canonicalize remote:local notation.
-canon_refs_list_for_fetch () {
- # If called from get_remote_default_refs_for_fetch
- # leave the branches in branch.${curr_branch}.merge alone,
- # or the first one otherwise; add prefix . to the rest
- # to prevent the secondary branches to be merged by default.
- merge_branches=
- curr_branch=
- if test "$1" = "-d"
- then
- shift ; remote="$1" ; shift
- set $(expand_refs_wildcard "$remote" "$@")
- is_explicit="$1"
- shift
- if test "$remote" = "$(get_default_remote)"
- then
- curr_branch=$(git symbolic-ref -q HEAD | \
- sed -e 's|^refs/heads/||')
- merge_branches=$(git config \
- --get-all "branch.${curr_branch}.merge")
- fi
- if test -z "$merge_branches" && test $is_explicit != explicit
- then
- merge_branches=..this.will.never.match.any.ref..
- fi
- fi
- for ref
- do
- force=
- case "$ref" in
- +*)
- ref=$(expr "z$ref" : 'z+\(.*\)')
- force=+
- ;;
- esac
- expr "z$ref" : 'z.*:' >/dev/null || ref="${ref}:"
- remote=$(expr "z$ref" : 'z\([^:]*\):')
- local=$(expr "z$ref" : 'z[^:]*:\(.*\)')
- dot_prefix=.
- if test -z "$merge_branches"
- then
- merge_branches=$remote
- dot_prefix=
- else
- for merge_branch in $merge_branches
- do
- [ "$remote" = "$merge_branch" ] &&
- dot_prefix= && break
- done
- fi
- case "$remote" in
- '' | HEAD ) remote=HEAD ;;
- refs/*) ;;
- heads/* | tags/* | remotes/* ) remote="refs/$remote" ;;
- *) remote="refs/heads/$remote" ;;
- esac
- case "$local" in
- '') local= ;;
- refs/*) ;;
- heads/* | tags/* | remotes/* ) local="refs/$local" ;;
- *) local="refs/heads/$local" ;;
- esac
-
- if local_ref_name=$(expr "z$local" : 'zrefs/\(.*\)')
- then
- git check-ref-format "$local_ref_name" ||
- die "* refusing to create funny ref '$local_ref_name' locally"
- fi
- echo "${dot_prefix}${force}${remote}:${local}"
- done
-}
-
-# Returns list of src: (no store), or src:dst (store)
-get_remote_default_refs_for_fetch () {
- data_source=$(get_data_source "$1")
- case "$data_source" in
- '')
- echo "HEAD:" ;;
- self)
- canon_refs_list_for_fetch -d "$1" \
- $(git for-each-ref --format='%(refname):')
- ;;
- config)
- canon_refs_list_for_fetch -d "$1" \
- $(git config --get-all "remote.$1.fetch") ;;
- branches)
- remote_branch=$(sed -ne '/#/s/.*#//p' "$GIT_DIR/branches/$1")
- case "$remote_branch" in '') remote_branch=master ;; esac
- echo "refs/heads/${remote_branch}:refs/heads/$1"
- ;;
- remotes)
- canon_refs_list_for_fetch -d "$1" $(sed -ne '/^Pull: */{
- s///p
- }' "$GIT_DIR/remotes/$1")
- ;;
- *)
- die "internal error: get-remote-default-ref-for-fetch $1" ;;
- esac
-}
-
-get_remote_refs_for_push () {
+get_remote_merge_branch () {
case "$#" in
- 0) die "internal error: get-remote-refs-for-push." ;;
- 1) get_remote_default_refs_for_push "$@" ;;
- *) shift; echo "$@" ;;
- esac
-}
-
-get_remote_refs_for_fetch () {
- case "$#" in
- 0)
- die "internal error: get-remote-refs-for-fetch." ;;
- 1)
- get_remote_default_refs_for_fetch "$@" ;;
- *)
- shift
- tag_just_seen=
- for ref
- do
- if test "$tag_just_seen"
- then
- echo "refs/tags/${ref}:refs/tags/${ref}"
- tag_just_seen=
- continue
- else
- case "$ref" in
- tag)
- tag_just_seen=yes
- continue
- ;;
- esac
- fi
- canon_refs_list_for_fetch "$ref"
- done
+ 0|1)
+ origin="$1"
+ default=$(get_default_remote)
+ test -z "$origin" && origin=$default
+ curr_branch=$(git symbolic-ref -q HEAD)
+ [ "$origin" = "$default" ] &&
+ echo $(git for-each-ref --format='%(upstream)' $curr_branch)
;;
- esac
-}
-
-resolve_alternates () {
- # original URL (xxx.git)
- top_=`expr "z$1" : 'z\([^:]*:/*[^/]*\)/'`
- while read path
- do
- case "$path" in
- \#* | '')
- continue ;;
- /*)
- echo "$top_$path/" ;;
- ../*)
- # relative -- ugly but seems to work.
- echo "$1/objects/$path/" ;;
- *)
- # exit code may not be caught by the reader.
- echo "bad alternate: $path"
- exit 1 ;;
- esac
- done
-}
-
-get_uploadpack () {
- data_source=$(get_data_source "$1")
- case "$data_source" in
- config)
- uplp=$(git config --get "remote.$1.uploadpack")
- echo ${uplp:-git-upload-pack}
- ;;
*)
- echo "git-upload-pack"
+ repo=$1
+ shift
+ ref=$1
+ # FIXME: It should return the tracking branch
+ # Currently only works with the default mapping
+ case "$ref" in
+ +*)
+ ref=$(expr "z$ref" : 'z+\(.*\)')
;;
+ esac
+ expr "z$ref" : 'z.*:' >/dev/null || ref="${ref}:"
+ remote=$(expr "z$ref" : 'z\([^:]*\):')
+ case "$remote" in
+ '' | HEAD ) remote=HEAD ;;
+ heads/*) remote=${remote#heads/} ;;
+ refs/heads/*) remote=${remote#refs/heads/} ;;
+ refs/* | tags/* | remotes/* ) remote=
+ esac
+
+ [ -n "$remote" ] && echo "refs/remotes/$repo/$remote"
esac
}
die "refusing to pull with rebase: your working tree is not up-to-date"
. git-parse-remote &&
- origin="$1"
- test -z "$origin" && origin=$(get_default_remote)
- reflist="$(get_remote_refs_for_fetch "$@" 2>/dev/null |
- sed "s|refs/heads/\(.*\):|\1|")" &&
+ reflist="$(get_remote_merge_branch "$@" 2>/dev/null)" &&
oldremoteref="$(git rev-parse -q --verify \
- "refs/remotes/$origin/$reflist")"
+ "$reflist")"
}
orig_head=$(git rev-parse -q --verify HEAD)
git fetch $verbosity --update-head-ok "$@" || exit 1
?*' '?*)
if test -z "$orig_head"
then
- echo >&2 "Cannot merge multiple branches into empty head"
- exit 1
+ die "Cannot merge multiple branches into empty head"
fi
if test true = "$rebase"
then
- echo >&2 "Cannot rebase onto multiple branches"
- exit 1
+ die "Cannot rebase onto multiple branches"
fi
;;
esac
if test -z "$OK_TO_SKIP_PRE_REBASE" &&
test -x "$GIT_DIR/hooks/pre-rebase"
then
- "$GIT_DIR/hooks/pre-rebase" ${1+"$@"} || {
- echo >&2 "The pre-rebase hook refused to rebase."
- exit 1
- }
+ "$GIT_DIR/hooks/pre-rebase" ${1+"$@"} ||
+ die "The pre-rebase hook refused to rebase."
fi
}
# The tree must be really really clean.
if ! git update-index --ignore-submodules --refresh; then
- echo >&2 "cannot rebase: you have unstaged changes"
- exit 1
+ die "cannot rebase: you have unstaged changes"
fi
diff=$(git diff-index --cached --name-status -r --ignore-submodules HEAD --)
case "$diff" in
. git-sh-setup
. git-parse-remote
+GIT_PAGER=
+export GIT_PAGER
+
base=$1
url=$2
head=${3-HEAD}
}")
if [ -z "$branch" ]; then
echo "warn: No branch of $url is at:" >&2
- git log --max-count=1 --pretty='format:warn: %h: %s' $headrev >&2
+ git log --max-count=1 --pretty='tformat:warn: %h: %s' $headrev >&2
echo "warn: Are you sure you pushed $head there?" >&2
echo >&2
echo >&2
status=1
fi
-PAGER=
-export PAGER
echo "The following changes since commit $baserev:"
git shortlog --max-count=1 $baserev | sed -e 's/^\(.\)/ \1/'
}
if ($suppress_cc{'all'}) {
- foreach my $entry (qw (ccmd cc author self sob body bodycc)) {
+ foreach my $entry (qw (cccmd cc author self sob body bodycc)) {
$suppress_cc{$entry} = 1;
}
delete $suppress_cc{'all'};
close F;
if (defined $cc_cmd && !$suppress_cc{'cccmd'}) {
- open(F, "$cc_cmd $t |")
+ open(F, "$cc_cmd \Q$t\E |")
or die "(cc-cmd) Could not execute '$cc_cmd'";
while(<F>) {
my $c = $_;
# Copyright (c) 2007 Lars Hjemli
USAGE="[--quiet] [--cached] \
-[add [-b branch] <repo> <path>]|[status|init|update [-i|--init] [-N|--no-fetch]|summary [-n|--summary-limit <n>] [<commit>]] \
+[add [-b branch] <repo> <path>]|[status|init|update [-i|--init] [-N|--no-fetch] [--rebase|--merge]|summary [-n|--summary-limit <n>] [<commit>]] \
[--] [<path>...]|[foreach <command>]|[sync [--] [<path>...]]"
OPTIONS_SPEC=
. git-sh-setup
reference="$1"
shift
;;
+ -m|--merge)
+ shift
+ update="merge"
+ ;;
--)
shift
break
action="rebase"
msg="rebased onto"
;;
+ merge)
+ command="git merge"
+ action="merge"
+ msg="merged in"
+ ;;
*)
command="git checkout $force -q"
action="checkout"
$sha1 = qr/[a-f\d]{40}/;
$sha1_short = qr/[a-f\d]{4,40}/;
my ($_stdin, $_help, $_edit,
- $_message, $_file,
+ $_message, $_file, $_branch_dest,
$_template, $_shared,
$_version, $_fetch_all, $_no_rebase, $_fetch_parent,
$_merge, $_strategy, $_dry_run, $_local,
'localtime' => \$Git::SVN::_localtime,
%remote_opts );
-my ($_trunk, $_tags, $_branches, $_stdlayout);
+my ($_trunk, @_tags, @_branches, $_stdlayout);
my %icv;
my %init_opts = ( 'template=s' => \$_template, 'shared:s' => \$_shared,
- 'trunk|T=s' => \$_trunk, 'tags|t=s' => \$_tags,
- 'branches|b=s' => \$_branches, 'prefix=s' => \$_prefix,
+ 'trunk|T=s' => \$_trunk, 'tags|t=s@' => \@_tags,
+ 'branches|b=s@' => \@_branches, 'prefix=s' => \$_prefix,
'stdlayout|s' => \$_stdlayout,
'minimize-url|m' => \$Git::SVN::_minimize_url,
'no-metadata' => sub { $icv{noMetadata} = 1 },
branch => [ \&cmd_branch,
'Create a branch in the SVN repository',
{ 'message|m=s' => \$_message,
+ 'destination|d=s' => \$_branch_dest,
'dry-run|n' => \$_dry_run,
'tag|t' => \$_tag } ],
tag => [ sub { $_tag = 1; cmd_branch(@_) },
'Create a tag in the SVN repository',
{ 'message|m=s' => \$_message,
+ 'destination|d=s' => \$_branch_dest,
'dry-run|n' => \$_dry_run } ],
'set-tree' => [ \&cmd_set_tree,
"Set an SVN repository to a git tree-ish",
'blame' => [ \&Git::SVN::Log::cmd_blame,
"Show what revision and author last modified each line of a file",
{ 'git-format' => \$_git_format } ],
+ 'reset' => [ \&cmd_reset,
+ "Undo fetches back to the specified SVN revision",
+ { 'revision|r=s' => \$_revision,
+ 'parent|p' => \$_fetch_parent } ],
);
my $cmd;
$cmd = $ARGV[$i];
splice @ARGV, $i, 1;
last;
+ } elsif ($ARGV[$i] eq 'help') {
+ $cmd = $ARGV[$i+1];
+ usage(0);
}
};
sub cmd_clone {
my ($url, $path) = @_;
if (!defined $path &&
- (defined $_trunk || defined $_branches || defined $_tags ||
+ (defined $_trunk || @_branches || @_tags ||
defined $_stdlayout) &&
$url !~ m#^[a-z\+]+://#) {
$path = $url;
sub cmd_init {
if (defined $_stdlayout) {
$_trunk = 'trunk' if (!defined $_trunk);
- $_tags = 'tags' if (!defined $_tags);
- $_branches = 'branches' if (!defined $_branches);
+ @_tags = 'tags' if (! @_tags);
+ @_branches = 'branches' if (! @_branches);
}
- if (defined $_trunk || defined $_branches || defined $_tags) {
+ if (defined $_trunk || @_branches || @_tags) {
return cmd_multi_init(@_);
}
my $url = shift or die "SVN repository location required ",
"as a command-line argument\n";
+ $url = canonicalize_url($url);
init_subdir(@_);
do_git_init_db();
'Cannot dcommit with a dirty index. Commit your changes first, '
. "or stash them with `git stash'.\n";
$head ||= 'HEAD';
+
+ my $old_head;
+ if ($head ne 'HEAD') {
+ $old_head = eval {
+ command_oneline([qw/symbolic-ref -q HEAD/])
+ };
+ if ($old_head) {
+ $old_head =~ s{^refs/heads/}{};
+ } else {
+ $old_head = eval { command_oneline(qw/rev-parse HEAD/) };
+ }
+ command(['checkout', $head], STDERR => 0);
+ }
+
my @refs;
- my ($url, $rev, $uuid, $gs) = working_head_info($head, \@refs);
+ my ($url, $rev, $uuid, $gs) = working_head_info('HEAD', \@refs);
unless ($gs) {
die "Unable to determine upstream SVN information from ",
"$head history.\nPerhaps the repository is empty.";
if (@diff) {
@refs = ();
my ($url_, $rev_, $uuid_, $gs_) =
- working_head_info($head, \@refs);
+ working_head_info('HEAD', \@refs);
my ($linear_refs_, $parents_) =
linearize_history($gs_, \@refs);
if (scalar(@$linear_refs) !=
}
}
}
+
+ if ($old_head) {
+ my $new_head = command_oneline(qw/rev-parse HEAD/);
+ my $new_is_symbolic = eval {
+ command_oneline(qw/symbolic-ref -q HEAD/);
+ };
+ if ($new_is_symbolic) {
+ print "dcommitted the branch ", $head, "\n";
+ } else {
+ print "dcommitted on a detached HEAD because you gave ",
+ "a revision argument.\n",
+ "The rewritten commit is: ", $new_head, "\n";
+ }
+ command(['checkout', $old_head], STDERR => 0);
+ }
+
unlink $gs->{index};
}
my ($src, $rev, undef, $gs) = working_head_info($head);
my $remote = Git::SVN::read_all_remotes()->{$gs->{repo_id}};
- my $glob = $remote->{ $_tag ? 'tags' : 'branches' };
+ my $allglobs = $remote->{ $_tag ? 'tags' : 'branches' };
+ my $glob;
+ if ($#{$allglobs} == 0) {
+ $glob = $allglobs->[0];
+ } else {
+ unless(defined $_branch_dest) {
+ die "Multiple ",
+ $_tag ? "tag" : "branch",
+ " paths defined for Subversion repository.\n",
+ "You must specify where you want to create the ",
+ $_tag ? "tag" : "branch",
+ " with the --destination argument.\n";
+ }
+ foreach my $g (@{$allglobs}) {
+ # SVN::Git::Editor could probably be moved to Git.pm..
+ my $re = SVN::Git::Editor::glob2pat($g->{path}->{left});
+ if ($_branch_dest =~ /$re/) {
+ $glob = $g;
+ last;
+ }
+ }
+ unless (defined $glob) {
+ die "Unknown ",
+ $_tag ? "tag" : "branch",
+ " destination $_branch_dest\n";
+ }
+ }
my ($lft, $rgt) = @{ $glob->{path} }{qw/left right/};
my $dst = join '/', $remote->{url}, $lft, $branch_name, ($rgt || ());
return $path;
}
+sub canonicalize_url {
+ my ($url) = @_;
+ $url =~ s#^([^:]+://[^/]*/)(.*)$#$1 . canonicalize_path($2)#e;
+ return $url;
+}
+
# get_svnprops(PATH)
# ------------------
# Helper for cmd_propget and cmd_proplist below.
sub cmd_multi_init {
my $url = shift;
- unless (defined $_trunk || defined $_branches || defined $_tags) {
+ unless (defined $_trunk || @_branches || @_tags) {
usage(1);
}
$_prefix = '' unless defined $_prefix;
if (defined $url) {
- $url =~ s#/+$##;
+ $url = canonicalize_url($url);
init_subdir(@_);
}
do_git_init_db();
undef, $trunk_ref);
}
}
- return unless defined $_branches || defined $_tags;
+ return unless @_branches || @_tags;
my $ra = $url ? Git::SVN::Ra->new($url) : undef;
- complete_url_ls_init($ra, $_branches, '--branches/-b', $_prefix);
- complete_url_ls_init($ra, $_tags, '--tags/-t', $_prefix . 'tags/');
+ foreach my $path (@_branches) {
+ complete_url_ls_init($ra, $path, '--branches/-b', $_prefix);
+ }
+ foreach my $path (@_tags) {
+ complete_url_ls_init($ra, $path, '--tags/-t', $_prefix.'tags/');
+ }
}
sub cmd_multi_fetch {
print $result, "\n";
}
+sub cmd_reset {
+ my $target = shift || $_revision or die "SVN revision required\n";
+ $target = $1 if $target =~ /^r(\d+)$/;
+ $target =~ /^\d+$/ or die "Numeric SVN revision expected\n";
+ my ($url, $rev, $uuid, $gs) = working_head_info('HEAD');
+ unless ($gs) {
+ die "Unable to determine upstream SVN information from ".
+ "history\n";
+ }
+ my ($r, $c) = $gs->find_rev_before($target, not $_fetch_parent);
+ $gs->rev_map_set($r, $c, 'reset', $uuid);
+ print "r$r = $c ($gs->{ref_id})\n";
+}
+
########################### utility functions #########################
sub rebase_cmd {
die "--prefix='$pfx' must have a trailing slash '/'\n";
}
command_noisy('config',
+ '--add',
"svn-remote.$gs->{repo_id}.$n",
"$remote_path:refs/remotes/$pfx*" .
('/*' x (($remote_path =~ tr/*/*/) - 1)) );
# read the max revs for wildcard expansion (branches/*, tags/*)
foreach my $t (qw/branches tags/) {
defined $remote->{$t} or next;
- push @globs, $remote->{$t};
+ push @globs, @{$remote->{$t}};
+
my $max_rev = eval { tmp_config(qw/--int --get/,
"svn-remote.$repo_id.${t}-maxRev") };
if (defined $max_rev && ($max_rev < $base)) {
} elsif (m!^(.+)\.(branches|tags)=
(.*):refs/remotes/(.+)\s*$/!x) {
my ($p, $g) = ($3, $4);
- my $rs = $r->{$1}->{$2} = {
- t => $2,
- remote => $1,
- path => Git::SVN::GlobSpec->new($p),
- ref => Git::SVN::GlobSpec->new($g) };
+ my $rs = {
+ t => $2,
+ remote => $1,
+ path => Git::SVN::GlobSpec->new($p),
+ ref => Git::SVN::GlobSpec->new($g) };
if (length($rs->{ref}->{right}) != 0) {
die "The '*' glob character must be the last ",
"character of '$g'\n";
}
+ push @{ $r->{$1}->{$2} }, $rs;
}
}
next if defined $repos_root && $repos_root ne $u;
my $fetch = $remotes->{$repo_id}->{fetch} || {};
- foreach (qw/branches tags/) {
- resolve_local_globs($u, $fetch,
- $remotes->{$repo_id}->{$_});
+ foreach my $t (qw/branches tags/) {
+ foreach my $globspec (@{$remotes->{$repo_id}->{$t}}) {
+ resolve_local_globs($u, $fetch, $globspec);
+ }
}
my $p = $path;
my $rwr = rewrite_root({repo_id => $repo_id});
croak "write: $!";
}
+sub _rev_map_reset {
+ my ($fh, $rev, $commit) = @_;
+ my $c = _rev_map_get($fh, $rev);
+ $c eq $commit or die "_rev_map_reset(@_) commit $c does not match!\n";
+ my $offset = sysseek($fh, 0, SEEK_CUR) or croak "seek: $!";
+ truncate $fh, $offset or croak "truncate: $!";
+}
+
sub mkfile {
my ($path) = @_;
unless (-e $path) {
my $db = $self->map_path($uuid);
my $db_lock = "$db.lock";
my $sig;
+ $update_ref ||= 0;
if ($update_ref) {
$SIG{INT} = $SIG{HUP} = $SIG{TERM} = $SIG{ALRM} = $SIG{PIPE} =
$SIG{USR1} = $SIG{USR2} = sub { $sig = $_[0] };
sysopen(my $fh, $db_lock, O_RDWR | O_CREAT)
or croak "Couldn't open $db_lock: $!\n";
- _rev_map_set($fh, $rev, $commit);
+ $update_ref eq 'reset' ? _rev_map_reset($fh, $rev, $commit) :
+ _rev_map_set($fh, $rev, $commit);
if ($sync) {
$fh->flush or die "Couldn't flush $db_lock: $!\n";
$fh->sync or die "Couldn't sync $db_lock: $!\n";
close $fh or croak $!;
if ($update_ref) {
$_head = $self;
- command_noisy('update-ref', '-m', "r$rev",
+ my $note = "";
+ $note = " ($update_ref)" if ($update_ref !~ /^\d*$/);
+ command_noisy('update-ref', '-m', "r$rev$note",
$self->refname, $commit);
}
rename $db_lock, $db or die "rev_map_set(@_): ", "Failed to rename: ",
return undef unless -e $map_path;
sysopen(my $fh, $map_path, O_RDONLY) or croak "open: $!";
+ my $c = _rev_map_get($fh, $rev);
+ close($fh) or croak "close: $!";
+ $c
+}
+
+sub _rev_map_get {
+ my ($fh, $rev) = @_;
+
binmode $fh or croak "binmode: $!";
my $size = (stat($fh))[7];
($size % 24) == 0 or croak "inconsistent size: $size";
if ($size == 0) {
- close $fh or croak "close: $fh";
return undef;
}
} elsif ($r > $rev) {
$u = $i - 24;
} else { # $r == $rev
- close($fh) or croak "close: $!";
return $c eq ('0' x 40) ? undef : $c;
}
}
- close($fh) or croak "close: $!";
undef;
}
my ($self, $rev, $eq_ok, $min_rev) = @_;
--$rev unless $eq_ok;
$min_rev ||= 1;
+ my $max_rev = $self->rev_map_max;
+ $rev = $max_rev if ($rev > $max_rev);
while ($rev >= $min_rev) {
if (my $c = $self->rev_map_get($rev)) {
return ($rev, $c);
alias_command);
new_argv = xrealloc(new_argv, sizeof(char *) *
- (count + *argcp + 1));
+ (count + *argcp));
/* insert after command name */
memcpy(new_argv + count, *argv + 1, sizeof(char *) * *argcp);
- new_argv[count+*argcp] = NULL;
*argv = new_argv;
*argcp += count - 1;
"--until=*" - "--before=*" - "--max-age=*" - "--min-age=*" -
"--author=*" - "--committer=*" - "--grep=*" - "-[iE]" -
"--remove-empty" - "--first-parent" - "--cherry-pick" -
- "-S*" - "--pickaxe-all" - "--pickaxe-regex" {
+ "-S*" - "--pickaxe-all" - "--pickaxe-regex" -
+ "--simplify-by-decoration" {
# These mean that we get a subset of the commits
set filtered 1
lappend glflags $arg
label .bleft.mid.labeldiffcontext -text " [mc "Lines of context"]: "
pack .bleft.mid.diff .bleft.mid.old .bleft.mid.new -side left
spinbox .bleft.mid.diffcontext -width 5 -font textfont \
- -from 1 -increment 1 -to 10000000 \
+ -from 0 -increment 1 -to 10000000 \
-validate all -validatecommand "diffcontextvalidate %P" \
-textvariable diffcontextstring
.bleft.mid.diffcontext set $diffcontext
}
set known_view_options {
- {perm b . {} {mc "Remember this view"}}
- {args t50= + {} {mc "Commits to include (arguments to git log):"}}
- {all b * "--all" {mc "Use all refs"}}
- {dorder b . {"--date-order" "-d"} {mc "Strictly sort by date"}}
- {lright b . "--left-right" {mc "Mark branch sides"}}
- {since t15 + {"--since=*" "--after=*"} {mc "Since date:"}}
- {until t15 . {"--until=*" "--before=*"} {mc "Until date:"}}
- {limit t10 + "--max-count=*" {mc "Max count:"}}
- {skip t10 . "--skip=*" {mc "Skip:"}}
- {first b . "--first-parent" {mc "Limit to first parent"}}
- {cmd t50= + {} {mc "Command to generate more commits to include:"}}
+ {perm b . {} {mc "Remember this view"}}
+ {reflabel l + {} {mc "References (space separated list):"}}
+ {refs t15 .. {} {mc "Branches & tags:"}}
+ {allrefs b *. "--all" {mc "All refs"}}
+ {branches b . "--branches" {mc "All (local) branches"}}
+ {tags b . "--tags" {mc "All tags"}}
+ {remotes b . "--remotes" {mc "All remote-tracking branches"}}
+ {commitlbl l + {} {mc "Commit Info (regular expressions):"}}
+ {author t15 .. "--author=*" {mc "Author:"}}
+ {committer t15 . "--committer=*" {mc "Committer:"}}
+ {loginfo t15 .. "--grep=*" {mc "Commit Message:"}}
+ {allmatch b .. "--all-match" {mc "Matches all Commit Info criteria"}}
+ {changes_l l + {} {mc "Changes to Files:"}}
+ {pickaxe_s r0 . {} {mc "Fixed String"}}
+ {pickaxe_t r1 . "--pickaxe-regex" {mc "Regular Expression"}}
+ {pickaxe t15 .. "-S*" {mc "Search string:"}}
+ {datelabel l + {} {mc "Commit Dates (\"2 weeks ago\", \"2009-03-17 15:27:38\", \"March 17, 2009 15:27:38\"):"}}
+ {since t15 .. {"--since=*" "--after=*"} {mc "Since:"}}
+ {until t15 . {"--until=*" "--before=*"} {mc "Until:"}}
+ {limit_lbl l + {} {mc "Limit and/or skip a number of revisions (positive integer):"}}
+ {limit t10 *. "--max-count=*" {mc "Number to show:"}}
+ {skip t10 . "--skip=*" {mc "Number to skip:"}}
+ {misc_lbl l + {} {mc "Miscellaneous options:"}}
+ {dorder b *. {"--date-order" "-d"} {mc "Strictly sort by date"}}
+ {lright b . "--left-right" {mc "Mark branch sides"}}
+ {first b . "--first-parent" {mc "Limit to first parent"}}
+ {smplhst b . "--simplify-by-decoration" {mc "Simple history"}}
+ {args t50 *. {} {mc "Additional arguments to git log:"}}
+ {allpaths path + {} {mc "Enter files and directories to include, one per line:"}}
+ {cmd t50= + {} {mc "Command to generate more commits to include:"}}
}
proc encode_view_opts {n} {
if {$patterns eq {}} continue
set pattern [lindex $patterns 0]
- set val $newviewopts($n,[lindex $opt 0])
-
if {[lindex $opt 1] eq "b"} {
+ set val $newviewopts($n,[lindex $opt 0])
if {$val} {
lappend rargs $pattern
}
+ } elseif {[regexp {^r(\d+)$} [lindex $opt 1] type value]} {
+ regexp {^(.*_)} [lindex $opt 0] uselessvar button_id
+ set val $newviewopts($n,$button_id)
+ if {$val eq $value} {
+ lappend rargs $pattern
+ }
} else {
+ set val $newviewopts($n,[lindex $opt 0])
set val [string trim $val]
if {$val ne {}} {
set pfix [string range $pattern 0 end-1]
}
}
}
+ set rargs [concat $rargs [shellsplit $newviewopts($n,refs)]]
return [concat $rargs [shellsplit $newviewopts($n,args)]]
}
global known_view_options newviewopts
foreach opt $known_view_options {
+ set id [lindex $opt 0]
if {[lindex $opt 1] eq "b"} {
+ # Checkboxes
+ set val 0
+ } elseif {[regexp {^r(\d+)$} [lindex $opt 1]]} {
+ # Radiobuttons
+ regexp {^(.*_)} $id uselessvar id
set val 0
} else {
+ # Text fields
set val {}
}
- set newviewopts($n,[lindex $opt 0]) $val
+ set newviewopts($n,$id) $val
}
set oargs [list]
+ set refargs [list]
foreach arg $view_args {
if {[regexp -- {^-([0-9]+)$} $arg arg cnt]
&& ![info exists found(limit)]} {
if {[info exists found($id)]} continue
foreach pattern [lindex $opt 3] {
if {![string match $pattern $arg]} continue
- if {[lindex $opt 1] ne "b"} {
+ if {[lindex $opt 1] eq "b"} {
+ # Check buttons
+ set val 1
+ } elseif {[regexp {^r(\d+)$} [lindex $opt 1] match num]} {
+ # Radio buttons
+ regexp {^(.*_)} $id uselessvar id
+ set val $num
+ } else {
+ # Text input fields
set size [string length $pattern]
set val [string range $arg [expr {$size-1}] end]
- } else {
- set val 1
}
set newviewopts($n,$id) $val
set found($id) 1
if {[info exists val]} break
}
if {[info exists val]} continue
- lappend oargs $arg
+ if {[regexp {^-} $arg]} {
+ lappend oargs $arg
+ } else {
+ lappend refargs $arg
+ }
}
+ set newviewopts($n,refs) [shellarglist $refargs]
set newviewopts($n,args) [shellarglist $oargs]
}
global known_view_options
toplevel $top
- wm title $top $title
+ wm title $top [concat $title [mc "-- criteria for selecting revisions"]]
make_transient $top .
# View name
frame $top.nfr
- label $top.nl -text [mc "Name"]
+ label $top.nl -text [mc "View Name:"]
entry $top.name -width 20 -textvariable newviewname($n)
pack $top.nfr -in $top -fill x -pady 5 -padx 3
- pack $top.nl -in $top.nfr -side left -padx {0 30}
- pack $top.name -in $top.nfr -side left
+ pack $top.nl -in $top.nfr -side left -padx {0 5}
+ pack $top.name -in $top.nfr -side left -padx {0 25}
# View options
set cframe $top.nfr
frame $cframe
pack $cframe -in $top -fill x -pady 3 -padx 3
set cexpand [expr {$flags eq "*"}]
+ } elseif {$flags eq ".." || $flags eq "*."} {
+ set cframe $top.fr$cnt
+ incr cnt
+ frame $cframe
+ pack $cframe -in $top -fill x -pady 3 -padx [list 15 3]
+ set cexpand [expr {$flags eq "*."}]
} else {
set lxpad 5
}
- if {$type eq "b"} {
+ if {$type eq "l"} {
+ label $cframe.l_$id -text $title
+ pack $cframe.l_$id -in $cframe -side left -pady [list 3 0] -anchor w
+ } elseif {$type eq "b"} {
checkbutton $cframe.c_$id -text $title -variable newviewopts($n,$id)
pack $cframe.c_$id -in $cframe -side left \
-padx [list $lxpad 0] -expand $cexpand -anchor w
+ } elseif {[regexp {^r(\d+)$} $type type sz]} {
+ regexp {^(.*_)} $id uselessvar button_id
+ radiobutton $cframe.c_$id -text $title -variable newviewopts($n,$button_id) -value $sz
+ pack $cframe.c_$id -in $cframe -side left \
+ -padx [list $lxpad 0] -expand $cexpand -anchor w
} elseif {[regexp {^t(\d+)$} $type type sz]} {
message $cframe.l_$id -aspect 1500 -text $title
entry $cframe.e_$id -width $sz -background $bgcolor \
-textvariable newviewopts($n,$id)
pack $cframe.l_$id -in $cframe -side top -pady [list 3 0] -anchor w
pack $cframe.e_$id -in $cframe -side top -fill x
+ } elseif {$type eq "path"} {
+ message $top.l -aspect 1500 -text $title
+ pack $top.l -in $top -side top -pady [list 3 0] -anchor w -padx 3
+ text $top.t -width 40 -height 5 -background $bgcolor -font uifont
+ if {[info exists viewfiles($n)]} {
+ foreach f $viewfiles($n) {
+ $top.t insert end $f
+ $top.t insert end "\n"
+ }
+ $top.t delete {end - 1c} end
+ $top.t mark set insert 0.0
+ }
+ pack $top.t -in $top -side top -pady [list 0 5] -fill both -expand 1 -padx 3
}
}
- # Path list
- message $top.l -aspect 1500 \
- -text [mc "Enter files and directories to include, one per line:"]
- pack $top.l -in $top -side top -pady [list 7 0] -anchor w -padx 3
- text $top.t -width 40 -height 5 -background $bgcolor -font uifont
- if {[info exists viewfiles($n)]} {
- foreach f $viewfiles($n) {
- $top.t insert end $f
- $top.t insert end "\n"
- }
- $top.t delete {end - 1c} end
- $top.t mark set insert 0.0
- }
- pack $top.t -in $top -side top -pady [list 0 5] -fill both -expand 1 -padx 3
frame $top.buts
button $top.buts.ok -text [mc "OK"] -command [list newviewok $top $n]
button $top.buts.apply -text [mc "Apply (F5)"] -command [list newviewok $top $n 1]
global diffcontextstring diffcontext
if {[string is integer -strict $diffcontextstring]} {
- if {$diffcontextstring > 0} {
+ if {$diffcontextstring >= 0} {
set diffcontext $diffcontextstring
reselectline
}
global ignorespace
global limitdiffs vfilelimit curview
global diffencoding targetline diffnparents
+ global git_version
- set cmd [diffcmd $ids "-p -C --cc --no-commit-id -U$diffcontext"]
+ set textconv {}
+ if {[package vcompare $git_version "1.6.1"] >= 0} {
+ set textconv "--textconv"
+ }
+ set cmd [diffcmd $ids "-p $textconv -C --cc --no-commit-id -U$diffcontext"]
if {$ignorespace} {
append cmd " -w"
}
set nullfile "/dev/null"
set have_tk85 [expr {[package vcompare $tk_version "8.5"] >= 0}]
+set git_version [join [lrange [split [lindex [exec git version] end] .] 0 2] .]
set runq {}
set history {}
# Translation of gitk to German.
# Copyright (C) 2007 Paul Mackerras.
# This file is distributed under the same license as the gitk package.
-# Christian Stimming <stimming@tuhh.de>, 2007
#
+# Christian Stimming <stimming@tuhh.de>, 2007.
+# Frederik Schwarzer <schwarzerf@gmail.com>, 2008.
msgid ""
msgstr ""
"Project-Id-Version: git-gui\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-12-06 20:40+0100\n"
-"PO-Revision-Date: 2008-12-06 20:45+0100\n"
+"POT-Creation-Date: 2009-05-12 21:55+0200\n"
+"PO-Revision-Date: 2009-05-12 22:18+0200\n"
"Last-Translator: Christian Stimming <stimming@tuhh.de>\n"
"Language-Team: German\n"
"MIME-Version: 1.0\n"
#: gitk:113
msgid "Couldn't get list of unmerged files:"
-msgstr "Liste der nicht-zusammengeführten Dateien nicht gefunden:"
+msgstr "Liste der nicht zusammengeführten Dateien nicht gefunden:"
-#: gitk:272
+#: gitk:268
msgid "Error parsing revisions:"
msgstr "Fehler beim Laden der Versionen:"
-#: gitk:327
+#: gitk:323
msgid "Error executing --argscmd command:"
-msgstr "Fehler beim --argscmd Kommando:"
+msgstr "Fehler beim Ausführen des --argscmd-Kommandos:"
-#: gitk:340
+#: gitk:336
msgid "No files selected: --merge specified but no files are unmerged."
msgstr ""
-"Keine Dateien ausgewählt: --merge angegeben, es existieren aber keine nicht-"
-"zusammengeführten Dateien."
+"Keine Dateien ausgewählt: Es wurde --merge angegeben, aber es existieren "
+"keine nicht zusammengeführten Dateien."
-#: gitk:343
+#: gitk:339
msgid ""
"No files selected: --merge specified but no unmerged files are within file "
"limit."
msgstr ""
-"Keine Dateien ausgewähle: --merge angegeben, aber keine nicht-"
-"zusammengeführten Dateien sind in der Dateiauswahl."
+"Keine Dateien ausgewählt: Es wurde --merge angegeben, aber es sind keine "
+"nicht zusammengeführten Dateien in der Dateiauswahl."
-#: gitk:365 gitk:503
+#: gitk:361 gitk:508
msgid "Error executing git log:"
-msgstr "Fehler beim Ausführen von git-log:"
+msgstr "Fehler beim Ausführen von »git log«:"
-#: gitk:378
+#: gitk:379 gitk:524
msgid "Reading"
msgstr "Lesen"
-#: gitk:438 gitk:3462
+#: gitk:439 gitk:4061
msgid "Reading commits..."
-msgstr "Versionen lesen..."
+msgstr "Versionen werden gelesen ..."
-#: gitk:441 gitk:1528 gitk:3465
+#: gitk:442 gitk:1560 gitk:4064
msgid "No commits selected"
-msgstr "Keine Versionen ausgewählt."
+msgstr "Keine Versionen ausgewählt"
-#: gitk:1399
+#: gitk:1436
msgid "Can't parse git log output:"
-msgstr "Ausgabe von git-log kann nicht erkannt werden:"
+msgstr "Ausgabe von »git log« kann nicht erkannt werden:"
-#: gitk:1605
+#: gitk:1656
msgid "No commit information available"
msgstr "Keine Versionsinformation verfügbar"
-#: gitk:1709 gitk:1731 gitk:3259 gitk:7764 gitk:9293 gitk:9466
+#: gitk:1791 gitk:1815 gitk:3854 gitk:8714 gitk:10250 gitk:10422
msgid "OK"
msgstr "Ok"
-#: gitk:1733 gitk:3260 gitk:7439 gitk:7510 gitk:7613 gitk:7660 gitk:7766
-#: gitk:9294 gitk:9467
+#: gitk:1817 gitk:3856 gitk:8311 gitk:8385 gitk:8495 gitk:8544 gitk:8716
+#: gitk:10251 gitk:10423
msgid "Cancel"
msgstr "Abbrechen"
-#: gitk:1811
+#: gitk:1917
msgid "Update"
msgstr "Aktualisieren"
-#: gitk:1812
+#: gitk:1918
msgid "Reload"
msgstr "Neu laden"
-#: gitk:1813
+#: gitk:1919
msgid "Reread references"
msgstr "Zweige neu laden"
-#: gitk:1814
+#: gitk:1920
msgid "List references"
msgstr "Zweige/Markierungen auflisten"
-#: gitk:1915
+#: gitk:1922
msgid "Start git gui"
msgstr "»git gui« starten"
-#: gitk:1917
+#: gitk:1924
msgid "Quit"
msgstr "Beenden"
-#: gitk:1810
+#: gitk:1916
msgid "File"
msgstr "Datei"
-#: gitk:1818
+#: gitk:1928
msgid "Preferences"
msgstr "Einstellungen"
-#: gitk:1817
+#: gitk:1927
msgid "Edit"
msgstr "Bearbeiten"
-#: gitk:1821
+#: gitk:1932
msgid "New view..."
-msgstr "Neue Ansicht..."
+msgstr "Neue Ansicht ..."
-#: gitk:1822
+#: gitk:1933
msgid "Edit view..."
-msgstr "Ansicht bearbeiten..."
+msgstr "Ansicht bearbeiten ..."
-#: gitk:1823
+#: gitk:1934
msgid "Delete view"
-msgstr "Ansicht löschen"
+msgstr "Ansicht entfernen"
-#: gitk:1825
+#: gitk:1936
msgid "All files"
msgstr "Alle Dateien"
-#: gitk:1820 gitk:3196
+#: gitk:1931 gitk:3666
msgid "View"
msgstr "Ansicht"
-#: gitk:1828 gitk:2487
+#: gitk:1941 gitk:1951 gitk:2650
msgid "About gitk"
msgstr "Ãœber gitk"
-#: gitk:1829
+#: gitk:1942 gitk:1956
msgid "Key bindings"
msgstr "Tastenkürzel"
-#: gitk:1827
+#: gitk:1940 gitk:1955
msgid "Help"
msgstr "Hilfe"
-#: gitk:1887
+#: gitk:2016
msgid "SHA1 ID: "
msgstr "SHA1:"
-#: gitk:1918
+#: gitk:2047
msgid "Row"
msgstr "Zeile"
-#: gitk:1949
+#: gitk:2078
msgid "Find"
msgstr "Suche"
-#: gitk:1950
+#: gitk:2079
msgid "next"
msgstr "nächste"
-#: gitk:1951
+#: gitk:2080
msgid "prev"
msgstr "vorige"
-#: gitk:1952
+#: gitk:2081
msgid "commit"
msgstr "Version nach"
-#: gitk:1955 gitk:1957 gitk:3617 gitk:3640 gitk:3664 gitk:5550 gitk:5621
+#: gitk:2084 gitk:2086 gitk:4222 gitk:4245 gitk:4269 gitk:6210 gitk:6282
+#: gitk:6366
msgid "containing:"
msgstr "Beschreibung:"
-#: gitk:1958 gitk:2954 gitk:2959 gitk:3692
+#: gitk:2087 gitk:3158 gitk:3163 gitk:4297
msgid "touching paths:"
msgstr "Dateien:"
-#: gitk:1959 gitk:3697
+#: gitk:2088 gitk:4302
msgid "adding/removing string:"
msgstr "Änderungen:"
-#: gitk:1968 gitk:1970
+#: gitk:2097 gitk:2099
msgid "Exact"
msgstr "Exakt"
-#: gitk:1970 gitk:3773 gitk:5518
+#: gitk:2099 gitk:4377 gitk:6178
msgid "IgnCase"
msgstr "Kein Groß/Klein"
-#: gitk:1970 gitk:3666 gitk:3771 gitk:5514
+#: gitk:2099 gitk:4271 gitk:4375 gitk:6174
msgid "Regexp"
msgstr "Regexp"
-#: gitk:1972 gitk:1973 gitk:3792 gitk:3822 gitk:3829 gitk:5641 gitk:5708
+#: gitk:2101 gitk:2102 gitk:4396 gitk:4426 gitk:4433 gitk:6302 gitk:6370
msgid "All fields"
msgstr "Alle Felder"
-#: gitk:1973 gitk:3790 gitk:3822 gitk:5580
+#: gitk:2102 gitk:4394 gitk:4426 gitk:6241
msgid "Headline"
msgstr "Ãœberschrift"
-#: gitk:1974 gitk:3790 gitk:5580 gitk:5708 gitk:6109
+#: gitk:2103 gitk:4394 gitk:6241 gitk:6370 gitk:6804
msgid "Comments"
msgstr "Beschreibung"
-#: gitk:1974 gitk:3790 gitk:3794 gitk:3829 gitk:5580 gitk:6045 gitk:7285
-#: gitk:7300
+#: gitk:2103 gitk:4394 gitk:4398 gitk:4433 gitk:6241 gitk:6739 gitk:7991
+#: gitk:8006
msgid "Author"
msgstr "Autor"
-#: gitk:1974 gitk:3790 gitk:5580 gitk:6047
+#: gitk:2103 gitk:4394 gitk:6241 gitk:6741
msgid "Committer"
msgstr "Eintragender"
-#: gitk:2003
+#: gitk:2132
msgid "Search"
-msgstr "Suche"
+msgstr "Suchen"
-#: gitk:2010
+#: gitk:2139
msgid "Diff"
msgstr "Vergleich"
-#: gitk:2012
+#: gitk:2141
msgid "Old version"
msgstr "Alte Version"
-#: gitk:2014
+#: gitk:2143
msgid "New version"
msgstr "Neue Version"
-#: gitk:2016
+#: gitk:2145
msgid "Lines of context"
msgstr "Kontextzeilen"
-#: gitk:2026
+#: gitk:2155
msgid "Ignore space change"
msgstr "Leerzeichenänderungen ignorieren"
-#: gitk:2084
+#: gitk:2213
msgid "Patch"
msgstr "Patch"
-#: gitk:2086
+#: gitk:2215
msgid "Tree"
msgstr "Baum"
-#: gitk:2213 gitk:2226
+#: gitk:2359 gitk:2376
msgid "Diff this -> selected"
-msgstr "Vergleich diese -> gewählte"
+msgstr "Vergleich: diese -> gewählte"
-#: gitk:2214 gitk:2227
+#: gitk:2360 gitk:2377
msgid "Diff selected -> this"
-msgstr "Vergleich gewählte -> diese"
+msgstr "Vergleich: gewählte -> diese"
-#: gitk:2215 gitk:2228
+#: gitk:2361 gitk:2378
msgid "Make patch"
msgstr "Patch erstellen"
-#: gitk:2216 gitk:7494
+#: gitk:2362 gitk:8369
msgid "Create tag"
msgstr "Markierung erstellen"
-#: gitk:2217 gitk:7593
+#: gitk:2363 gitk:8475
msgid "Write commit to file"
msgstr "Version in Datei schreiben"
-#: gitk:2218 gitk:7647
+#: gitk:2364 gitk:8532
msgid "Create new branch"
msgstr "Neuen Zweig erstellen"
-#: gitk:2219
+#: gitk:2365
msgid "Cherry-pick this commit"
msgstr "Diese Version pflücken"
-#: gitk:2220
+#: gitk:2366
msgid "Reset HEAD branch to here"
msgstr "HEAD-Zweig auf diese Version zurücksetzen"
-#: gitk:2234
+#: gitk:2367
+msgid "Mark this commit"
+msgstr "Lesezeichen setzen"
+
+#: gitk:2368
+msgid "Return to mark"
+msgstr "Zum Lesezeichen"
+
+#: gitk:2369
+msgid "Find descendant of this and mark"
+msgstr "Abkömmling von Lesezeichen und dieser Version finden"
+
+#: gitk:2370
+msgid "Compare with marked commit"
+msgstr "Mit Lesezeichen vergleichen"
+
+#: gitk:2384
msgid "Check out this branch"
msgstr "Auf diesen Zweig umstellen"
-#: gitk:2235
+#: gitk:2385
msgid "Remove this branch"
msgstr "Zweig löschen"
-#: gitk:2242
+#: gitk:2392
msgid "Highlight this too"
msgstr "Diesen auch hervorheben"
-#: gitk:2243
+#: gitk:2393
msgid "Highlight this only"
msgstr "Nur diesen hervorheben"
-#: gitk:2244
+#: gitk:2394
msgid "External diff"
-msgstr "Externer Vergleich"
+msgstr "Externes Diff-Programm"
-#: gitk:2255
+#: gitk:2395
msgid "Blame parent commit"
msgstr "Annotieren der Elternversion"
-#: gitk:2360
+#: gitk:2402
msgid "Show origin of this line"
msgstr "Herkunft dieser Zeile anzeigen"
-#: gitk:2361
+#: gitk:2403
msgid "Run git gui blame on this line"
-msgstr "Annotieren (»git gui blame«) von dieser Zeile"
+msgstr "Diese Zeile annotieren (»git gui blame«)"
-#: gitk:2606
+#: gitk:2652
msgid ""
"\n"
"Gitk - a commit viewer for git\n"
"Use and redistribute under the terms of the GNU General Public License"
msgstr ""
"\n"
-"Gitk - eine Visualisierung der Git Historie\n"
+"Gitk - eine Visualisierung der Git-Historie\n"
"\n"
"Copyright © 2005-2008 Paul Mackerras\n"
"\n"
"Benutzung und Weiterverbreitung gemäß den Bedingungen der GNU General Public "
"License"
-#: gitk:2496 gitk:2557 gitk:7943
+#: gitk:2660 gitk:2722 gitk:8897
msgid "Close"
msgstr "Schließen"
-#: gitk:2515
+#: gitk:2679
msgid "Gitk key bindings"
-msgstr "Gitk Tastaturbelegung"
+msgstr "Gitk-Tastaturbelegung"
-#: gitk:2517
+#: gitk:2682
msgid "Gitk key bindings:"
-msgstr "Gitk Tastaturbelegung:"
+msgstr "Gitk-Tastaturbelegung:"
-#: gitk:2519
+#: gitk:2684
#, tcl-format
msgid "<%s-Q>\t\tQuit"
msgstr "<%s-Q>\t\tBeenden"
-#: gitk:2520
+#: gitk:2685
msgid "<Home>\t\tMove to first commit"
msgstr "<Pos1>\t\tZur neuesten Version springen"
-#: gitk:2521
+#: gitk:2686
msgid "<End>\t\tMove to last commit"
msgstr "<Ende>\t\tZur ältesten Version springen"
-#: gitk:2522
+#: gitk:2687
msgid "<Up>, p, i\tMove up one commit"
msgstr "<Hoch>, p, i\tNächste neuere Version"
-#: gitk:2523
+#: gitk:2688
msgid "<Down>, n, k\tMove down one commit"
msgstr "<Runter>, n, k\tNächste ältere Version"
-#: gitk:2524
+#: gitk:2689
msgid "<Left>, z, j\tGo back in history list"
msgstr "<Links>, z, j\tEine Version zurückgehen"
-#: gitk:2525
+#: gitk:2690
msgid "<Right>, x, l\tGo forward in history list"
msgstr "<Rechts>, x, l\tEine Version weitergehen"
-#: gitk:2526
+#: gitk:2691
msgid "<PageUp>\tMove up one page in commit list"
msgstr "<BildHoch>\tEine Seite nach oben blättern"
-#: gitk:2527
+#: gitk:2692
msgid "<PageDown>\tMove down one page in commit list"
msgstr "<BildRunter>\tEine Seite nach unten blättern"
-#: gitk:2528
+#: gitk:2693
#, tcl-format
msgid "<%s-Home>\tScroll to top of commit list"
msgstr "<%s-Pos1>\tZum oberen Ende der Versionsliste blättern"
-#: gitk:2529
+#: gitk:2694
#, tcl-format
msgid "<%s-End>\tScroll to bottom of commit list"
msgstr "<%s-Ende>\tZum unteren Ende der Versionsliste blättern"
-#: gitk:2530
+#: gitk:2695
#, tcl-format
msgid "<%s-Up>\tScroll commit list up one line"
msgstr "<%s-Hoch>\tVersionsliste eine Zeile nach oben blättern"
-#: gitk:2531
+#: gitk:2696
#, tcl-format
msgid "<%s-Down>\tScroll commit list down one line"
msgstr "<%s-Runter>\tVersionsliste eine Zeile nach unten blättern"
-#: gitk:2532
+#: gitk:2697
#, tcl-format
msgid "<%s-PageUp>\tScroll commit list up one page"
-msgstr "<%s-BildHoch>\tVersionsliste eine Seite hoch blättern"
+msgstr "<%s-BildHoch>\tVersionsliste eine Seite nach oben blättern"
-#: gitk:2533
+#: gitk:2698
#, tcl-format
msgid "<%s-PageDown>\tScroll commit list down one page"
msgstr "<%s-BildRunter>\tVersionsliste eine Seite nach unten blättern"
-#: gitk:2534
+#: gitk:2699
msgid "<Shift-Up>\tFind backwards (upwards, later commits)"
msgstr "<Umschalt-Hoch>\tRückwärts suchen (nach oben; neuere Versionen)"
-#: gitk:2535
+#: gitk:2700
msgid "<Shift-Down>\tFind forwards (downwards, earlier commits)"
msgstr "<Umschalt-Runter> Suchen (nach unten; ältere Versionen)"
-#: gitk:2536
+#: gitk:2701
msgid "<Delete>, b\tScroll diff view up one page"
msgstr "<Entf>, b\t\tVergleich eine Seite nach oben blättern"
-#: gitk:2537
+#: gitk:2702
msgid "<Backspace>\tScroll diff view up one page"
msgstr "<Löschtaste>\tVergleich eine Seite nach oben blättern"
-#: gitk:2538
+#: gitk:2703
msgid "<Space>\t\tScroll diff view down one page"
msgstr "<Leertaste>\tVergleich eine Seite nach unten blättern"
-#: gitk:2539
+#: gitk:2704
msgid "u\t\tScroll diff view up 18 lines"
-msgstr "u\t\tVergleich um 18 Zeilen nach oben (»up«) blättern"
+msgstr "u\t\tVergleich um 18 Zeilen nach oben blättern"
-#: gitk:2540
+#: gitk:2705
msgid "d\t\tScroll diff view down 18 lines"
-msgstr "d\t\tVergleich um 18 Zeilen nach unten (»down«) blättern"
+msgstr "d\t\tVergleich um 18 Zeilen nach unten blättern"
-#: gitk:2541
+#: gitk:2706
#, tcl-format
msgid "<%s-F>\t\tFind"
msgstr "<%s-F>\t\tSuchen"
-#: gitk:2542
+#: gitk:2707
#, tcl-format
msgid "<%s-G>\t\tMove to next find hit"
msgstr "<%s-G>\t\tWeitersuchen"
-#: gitk:2543
+#: gitk:2708
msgid "<Return>\tMove to next find hit"
msgstr "<Eingabetaste>\tWeitersuchen"
-#: gitk:2544
-msgid "/\t\tMove to next find hit, or redo find"
-msgstr "/\t\tWeitersuchen oder neue Suche beginnen"
+#: gitk:2709
+msgid "/\t\tFocus the search box"
+msgstr "/\t\tTastaturfokus ins Suchfeld"
-#: gitk:2545
+#: gitk:2710
msgid "?\t\tMove to previous find hit"
msgstr "?\t\tRückwärts weitersuchen"
-#: gitk:2546
+#: gitk:2711
msgid "f\t\tScroll diff view to next file"
-msgstr "f\t\tVergleich zur nächsten Datei (»file«) blättern"
+msgstr "f\t\tVergleich zur nächsten Datei blättern"
-#: gitk:2547
+#: gitk:2712
#, tcl-format
msgid "<%s-S>\t\tSearch for next hit in diff view"
msgstr "<%s-S>\t\tWeitersuchen im Vergleich"
-#: gitk:2548
+#: gitk:2713
#, tcl-format
msgid "<%s-R>\t\tSearch for previous hit in diff view"
msgstr "<%s-R>\t\tRückwärts weitersuchen im Vergleich"
-#: gitk:2549
+#: gitk:2714
#, tcl-format
msgid "<%s-KP+>\tIncrease font size"
-msgstr "<%s-Nummerblock-Plus>\tSchriftgröße vergrößern"
+msgstr "<%s-Nummerblock-Plus>\tSchrift vergrößern"
-#: gitk:2550
+#: gitk:2715
#, tcl-format
msgid "<%s-plus>\tIncrease font size"
-msgstr "<%s-Plus>\tSchriftgröße vergrößern"
+msgstr "<%s-Plus>\tSchrift vergrößern"
-#: gitk:2551
+#: gitk:2716
#, tcl-format
msgid "<%s-KP->\tDecrease font size"
-msgstr "<%s-Nummernblock-> Schriftgröße verkleinern"
+msgstr "<%s-Nummernblock-Minus> Schrift verkleinern"
-#: gitk:2552
+#: gitk:2717
#, tcl-format
msgid "<%s-minus>\tDecrease font size"
-msgstr "<%s-Minus>\tSchriftgröße verkleinern"
+msgstr "<%s-Minus>\tSchrift verkleinern"
-#: gitk:2553
+#: gitk:2718
msgid "<F5>\t\tUpdate"
msgstr "<F5>\t\tAktualisieren"
-#: gitk:2979
+#: gitk:3173
#, tcl-format
msgid "Error getting \"%s\" from %s:"
msgstr "Fehler beim Holen von »%s« von »%s«:"
-#: gitk:3036 gitk:3045
+#: gitk:3230 gitk:3239
#, tcl-format
msgid "Error creating temporary directory %s:"
-msgstr "Fehler beim Erzeugen eines temporären Verzeichnisses »%s«:"
+msgstr "Fehler beim Erzeugen des temporären Verzeichnisses »%s«:"
-#: gitk:3058
+#: gitk:3251
msgid "command failed:"
msgstr "Kommando fehlgeschlagen:"
-#: gitk:3078
+#: gitk:3397
msgid "No such commit"
msgstr "Version nicht gefunden"
-#: gitk:3083
+#: gitk:3411
msgid "git gui blame: command failed:"
msgstr "git gui blame: Kommando fehlgeschlagen:"
-#: gitk:3398
+#: gitk:3442
#, tcl-format
msgid "Couldn't read merge head: %s"
msgstr "Zusammenführungs-Spitze konnte nicht gelesen werden: %s"
-#: gitk:3406
+#: gitk:3450
#, tcl-format
msgid "Error reading index: %s"
msgstr "Fehler beim Lesen der Bereitstellung (»index«): %s"
-#: gitk:3431
+#: gitk:3475
#, tcl-format
msgid "Couldn't start git blame: %s"
msgstr "»git blame« konnte nicht gestartet werden: %s"
-#: gitk:3434 gitk:6160
+#: gitk:3478 gitk:6209
msgid "Searching"
msgstr "Suchen"
-#: gitk:3466
+#: gitk:3510
#, tcl-format
msgid "Error running git blame: %s"
msgstr "Fehler beim Ausführen von »git blame«: %s"
-#: gitk:3494
+#: gitk:3538
#, tcl-format
msgid "That line comes from commit %s, which is not in this view"
msgstr ""
-"Diese Zeile stammt aus Version %s, welche nicht in dieser Ansicht gezeigt "
-"wird."
+"Diese Zeile stammt aus Version %s, die nicht in dieser Ansicht gezeigt wird"
-#: gitk:3508
+#: gitk:3552
msgid "External diff viewer failed:"
-msgstr "Externes Vergleich-(Diff-)Programm fehlgeschlagen:"
+msgstr "Externes Diff-Programm fehlgeschlagen:"
-#: gitk:3210
+#: gitk:3670
msgid "Gitk view definition"
-msgstr "Gitk Ansichten"
+msgstr "Gitk-Ansichten"
-#: gitk:3630
+#: gitk:3674
msgid "Remember this view"
msgstr "Diese Ansicht speichern"
-#: gitk:3232
+#: gitk:3675
msgid "Commits to include (arguments to git log):"
-msgstr "Versionen anzeigen (Argumente von git-log):"
+msgstr "Versionen anzeigen (Argumente von git log):"
-#: gitk:3632
+#: gitk:3676
msgid "Use all refs"
msgstr "Alle Zweige verwenden"
-#: gitk:3633
+#: gitk:3677
msgid "Strictly sort by date"
msgstr "Streng nach Datum sortieren"
-#: gitk:3634
+#: gitk:3678
msgid "Mark branch sides"
msgstr "Zweig-Seiten markieren"
-#: gitk:3635
+#: gitk:3679
msgid "Since date:"
msgstr "Von Datum:"
-#: gitk:3636
+#: gitk:3680
msgid "Until date:"
msgstr "Bis Datum:"
-#: gitk:3637
+#: gitk:3681
msgid "Max count:"
msgstr "Max. Anzahl:"
-#: gitk:3638
+#: gitk:3682
msgid "Skip:"
msgstr "Ãœberspringen:"
-#: gitk:3639
+#: gitk:3683
msgid "Limit to first parent"
msgstr "Auf erste Elternversion beschränken"
-#: gitk:3640
+#: gitk:3684
msgid "Command to generate more commits to include:"
msgstr "Versionsliste durch folgendes Kommando erzeugen lassen:"
-#: gitk:3749
+#: gitk:3780
+msgid "Gitk: edit view"
+msgstr "Gitk: Ansicht bearbeiten"
+
+#: gitk:3793
msgid "Name"
msgstr "Name"
-#: gitk:3797
+#: gitk:3841
msgid "Enter files and directories to include, one per line:"
msgstr "Folgende Dateien und Verzeichnisse anzeigen (eine pro Zeile):"
-#: gitk:3811
+#: gitk:3855
msgid "Apply (F5)"
msgstr "Anwenden (F5)"
-#: gitk:3849
+#: gitk:3893
msgid "Error in commit selection arguments:"
msgstr "Fehler in den ausgewählten Versionen:"
-#: gitk:3347 gitk:3399 gitk:3842 gitk:3856 gitk:5060 gitk:10141 gitk:10142
+#: gitk:3946 gitk:3998 gitk:4446 gitk:4460 gitk:5721 gitk:11114 gitk:11115
msgid "None"
msgstr "Keine"
-#: gitk:3790 gitk:5580 gitk:7287 gitk:7302
+#: gitk:4394 gitk:6241 gitk:7993 gitk:8008
msgid "Date"
msgstr "Datum"
-#: gitk:3790 gitk:5580
+#: gitk:4394 gitk:6241
msgid "CDate"
msgstr "Eintragedatum"
-#: gitk:3939 gitk:3944
+#: gitk:4543 gitk:4548
msgid "Descendant"
msgstr "Abkömmling"
-#: gitk:3940
+#: gitk:4544
msgid "Not descendant"
-msgstr "Nicht Abkömmling"
+msgstr "Kein Abkömmling"
-#: gitk:3947 gitk:3952
+#: gitk:4551 gitk:4556
msgid "Ancestor"
msgstr "Vorgänger"
-#: gitk:3948
+#: gitk:4552
msgid "Not ancestor"
-msgstr "Nicht Vorgänger"
+msgstr "Kein Vorgänger"
-#: gitk:4187
+#: gitk:4842
msgid "Local changes checked in to index but not committed"
msgstr "Lokale Änderungen bereitgestellt, aber nicht eingetragen"
-#: gitk:4220
+#: gitk:4878
msgid "Local uncommitted changes, not checked in to index"
msgstr "Lokale Änderungen, nicht bereitgestellt"
-#: gitk:6673
+#: gitk:6559
+msgid "many"
+msgstr "viele"
+
+#: gitk:6743
msgid "Tags:"
msgstr "Markierungen:"
-#: gitk:6066 gitk:6072 gitk:7280
+#: gitk:6760 gitk:6766 gitk:7986
msgid "Parent"
msgstr "Eltern"
-#: gitk:6077
+#: gitk:6771
msgid "Child"
msgstr "Kind"
-#: gitk:6086
+#: gitk:6780
msgid "Branch"
msgstr "Zweig"
-#: gitk:6089
+#: gitk:6783
msgid "Follows"
msgstr "Folgt auf"
-#: gitk:6092
+#: gitk:6786
msgid "Precedes"
msgstr "Vorgänger von"
-#: gitk:7209
+#: gitk:7279
#, tcl-format
msgid "Error getting diffs: %s"
msgstr "Fehler beim Laden des Vergleichs: %s"
-#: gitk:7748
+#: gitk:7819
msgid "Goto:"
msgstr "Gehe zu:"
-#: gitk:7115
+#: gitk:7821
msgid "SHA1 ID:"
msgstr "SHA1-Hashwert:"
-#: gitk:7134
+#: gitk:7840
#, tcl-format
msgid "Short SHA1 id %s is ambiguous"
msgstr "Kurzer SHA1-Hashwert »%s« ist mehrdeutig"
-#: gitk:7146
+#: gitk:7852
#, tcl-format
msgid "SHA1 id %s is not known"
-msgstr "SHA1-Hashwert »%s« unbekannt"
+msgstr "SHA1-Hashwert »%s« ist unbekannt"
-#: gitk:7148
+#: gitk:7854
#, tcl-format
msgid "Tag/Head %s is not known"
msgstr "Markierung/Zweig »%s« ist unbekannt"
-#: gitk:7290
+#: gitk:7996
msgid "Children"
msgstr "Kinder"
-#: gitk:7347
+#: gitk:8053
#, tcl-format
msgid "Reset %s branch to here"
msgstr "Zweig »%s« hierher zurücksetzen"
-#: gitk:7349
+#: gitk:8055
msgid "Detached head: can't reset"
msgstr "Zweigspitze ist abgetrennt: Zurücksetzen nicht möglich"
-#: gitk:7381
+#: gitk:8164 gitk:8170
+msgid "Skipping merge commit "
+msgstr "Überspringe Zusammenführungs-Version "
+
+#: gitk:8179 gitk:8184
+msgid "Error getting patch ID for "
+msgstr "Fehler beim Holen der Patch-ID für "
+
+#: gitk:8180 gitk:8185
+msgid " - stopping\n"
+msgstr " - Abbruch.\n"
+
+#: gitk:8190 gitk:8193 gitk:8201 gitk:8211 gitk:8220
+msgid "Commit "
+msgstr "Version "
+
+#: gitk:8194
+msgid ""
+" is the same patch as\n"
+" "
+msgstr ""
+" ist das gleiche Patch wie\n"
+" "
+
+#: gitk:8202
+msgid ""
+" differs from\n"
+" "
+msgstr ""
+" ist unterschiedlich von\n"
+" "
+
+#: gitk:8204
+msgid "- stopping\n"
+msgstr "- Abbruch.\n"
+
+#: gitk:8212 gitk:8221
+#, tcl-format
+msgid " has %s children - stopping\n"
+msgstr " hat %s Kinder. Abbruch\n"
+
+#: gitk:8252
msgid "Top"
msgstr "Oben"
-#: gitk:7382
+#: gitk:8253
msgid "From"
msgstr "Von"
-#: gitk:7387
+#: gitk:8258
msgid "To"
msgstr "bis"
-#: gitk:7410
+#: gitk:8282
msgid "Generate patch"
msgstr "Patch erstellen"
-#: gitk:7412
+#: gitk:8284
msgid "From:"
msgstr "Von:"
-#: gitk:7421
+#: gitk:8293
msgid "To:"
msgstr "bis:"
-#: gitk:7430
+#: gitk:8302
msgid "Reverse"
msgstr "Umgekehrt"
-#: gitk:7432 gitk:7607
+#: gitk:8304 gitk:8489
msgid "Output file:"
msgstr "Ausgabedatei:"
-#: gitk:7438
+#: gitk:8310
msgid "Generate"
msgstr "Erzeugen"
-#: gitk:7474
+#: gitk:8348
msgid "Error creating patch:"
-msgstr "Fehler beim Patch erzeugen:"
+msgstr "Fehler beim Erzeugen des Patches:"
-#: gitk:7496 gitk:7595 gitk:7649
+#: gitk:8371 gitk:8477 gitk:8534
msgid "ID:"
msgstr "ID:"
-#: gitk:7505
+#: gitk:8380
msgid "Tag name:"
msgstr "Markierungsname:"
-#: gitk:7509 gitk:7659
+#: gitk:8384 gitk:8543
msgid "Create"
msgstr "Erstellen"
-#: gitk:7524
+#: gitk:8401
msgid "No tag name specified"
msgstr "Kein Markierungsname angegeben"
-#: gitk:7528
+#: gitk:8405
#, tcl-format
msgid "Tag \"%s\" already exists"
msgstr "Markierung »%s« existiert bereits."
-#: gitk:7534
+#: gitk:8411
msgid "Error creating tag:"
-msgstr "Fehler bei Markierung erstellen:"
+msgstr "Fehler beim Erstellen der Markierung:"
-#: gitk:7604
+#: gitk:8486
msgid "Command:"
msgstr "Kommando:"
-#: gitk:7612
+#: gitk:8494
msgid "Write"
msgstr "Schreiben"
-#: gitk:7628
+#: gitk:8512
msgid "Error writing commit:"
msgstr "Fehler beim Schreiben der Version:"
-#: gitk:7654
+#: gitk:8539
msgid "Name:"
msgstr "Name:"
-#: gitk:7674
+#: gitk:8562
msgid "Please specify a name for the new branch"
msgstr "Bitte geben Sie einen Namen für den neuen Zweig an."
-#: gitk:8328
+#: gitk:8567
#, tcl-format
msgid "Branch '%s' already exists. Overwrite?"
msgstr "Zweig »%s« existiert bereits. Soll er überschrieben werden?"
-#: gitk:8394
+#: gitk:8633
#, tcl-format
msgid "Commit %s is already included in branch %s -- really re-apply it?"
msgstr ""
"Version »%s« ist bereits im Zweig »%s« enthalten -- trotzdem erneut "
"eintragen?"
-#: gitk:7718
+#: gitk:8638
msgid "Cherry-picking"
msgstr "Version pflücken"
-#: gitk:8408
+#: gitk:8647
#, tcl-format
msgid ""
"Cherry-pick failed because of local changes to file '%s'.\n"
msgstr ""
"Pflücken fehlgeschlagen, da noch lokale Änderungen in Datei »%s«\n"
"vorliegen. Bitte diese Änderungen eintragen, zurücksetzen oder\n"
-"zwischenspeichern (»git stash») und dann erneut versuchen."
+"zwischenspeichern (»git stash«) und dann erneut versuchen."
-#: gitk:8414
+#: gitk:8653
msgid ""
"Cherry-pick failed because of merge conflict.\n"
"Do you wish to run git citool to resolve it?"
msgstr ""
"Pflücken fehlgeschlagen, da ein Zusammenführungs-Konflikt aufgetreten\n"
-"ist. Soll das »git citool« (Zusammenführungs-Werkzeug) aufgerufen\n"
+"ist. Soll das Zusammenführungs-Werkzeug (»git citool«) aufgerufen\n"
"werden, um diesen Konflikt aufzulösen?"
-#: gitk:8430
+#: gitk:8669
msgid "No changes committed"
msgstr "Keine Änderungen eingetragen"
-#: gitk:7745
+#: gitk:8695
msgid "Confirm reset"
msgstr "Zurücksetzen bestätigen"
-#: gitk:7747
+#: gitk:8697
#, tcl-format
msgid "Reset branch %s to %s?"
msgstr "Zweig »%s« auf »%s« zurücksetzen?"
-#: gitk:7751
+#: gitk:8701
msgid "Reset type:"
msgstr "Art des Zurücksetzens:"
-#: gitk:7755
+#: gitk:8705
msgid "Soft: Leave working tree and index untouched"
msgstr "Harmlos: Arbeitskopie und Bereitstellung unverändert"
-#: gitk:7758
+#: gitk:8708
msgid "Mixed: Leave working tree untouched, reset index"
msgstr ""
"Gemischt: Arbeitskopie unverändert,\n"
"Bereitstellung zurückgesetzt"
-#: gitk:7761
+#: gitk:8711
msgid ""
"Hard: Reset working tree and index\n"
"(discard ALL local changes)"
"Hart: Arbeitskopie und Bereitstellung\n"
"(Alle lokalen Änderungen werden gelöscht)"
-#: gitk:7777
+#: gitk:8728
msgid "Resetting"
msgstr "Zurücksetzen"
-#: gitk:7834
+#: gitk:8785
msgid "Checking out"
msgstr "Umstellen"
-#: gitk:7885
+#: gitk:8838
msgid "Cannot delete the currently checked-out branch"
msgstr ""
"Der Zweig, auf den die Arbeitskopie momentan umgestellt ist, kann nicht "
"gelöscht werden."
-#: gitk:7891
+#: gitk:8844
#, tcl-format
msgid ""
"The commits on branch %s aren't on any other branch.\n"
"Die Versionen auf Zweig »%s« existieren auf keinem anderen Zweig.\n"
"Zweig »%s« trotzdem löschen?"
-#: gitk:7922
+#: gitk:8875
#, tcl-format
msgid "Tags and heads: %s"
msgstr "Markierungen und Zweige: %s"
-#: gitk:7936
+#: gitk:8890
msgid "Filter"
msgstr "Filtern"
-#: gitk:8230
+#: gitk:9185
msgid ""
"Error reading commit topology information; branch and preceding/following "
"tag information will be incomplete."
msgstr ""
-"Fehler beim Lesen der Strukturinformationen; Zweige und Vorgänger/Nachfolger "
-"Informationen werden unvollständig sein."
+"Fehler beim Lesen der Strukturinformationen; Zweige und Informationen zu "
+"Vorgänger/Nachfolger werden unvollständig sein."
-#: gitk:9216
+#: gitk:10171
msgid "Tag"
msgstr "Markierung"
-#: gitk:9216
+#: gitk:10171
msgid "Id"
msgstr "Id"
-#: gitk:9262
+#: gitk:10219
msgid "Gitk font chooser"
-msgstr "Gitk Schriften wählen"
+msgstr "Gitk-Schriften wählen"
-#: gitk:9279
+#: gitk:10236
msgid "B"
msgstr "F"
-#: gitk:9282
+#: gitk:10239
msgid "I"
msgstr "K"
-#: gitk:9375
+#: gitk:10334
msgid "Gitk preferences"
-msgstr "Gitk Einstellungen"
+msgstr "Gitk-Einstellungen"
-#: gitk:9376
+#: gitk:10336
msgid "Commit list display options"
-msgstr "Anzeige Versionsliste"
+msgstr "Anzeige der Versionsliste"
-#: gitk:9379
+#: gitk:10339
msgid "Maximum graph width (lines)"
msgstr "Maximale Graphenbreite (Zeilen)"
-#: gitk:9383
+#: gitk:10343
#, tcl-format
msgid "Maximum graph width (% of pane)"
msgstr "Maximale Graphenbreite (% des Fensters)"
-#: gitk:9388
+#: gitk:10347
msgid "Show local changes"
msgstr "Lokale Änderungen anzeigen"
-#: gitk:9393
+#: gitk:10350
msgid "Auto-select SHA1"
-msgstr "SHA1-Hashwert automatisch markieren"
+msgstr "SHA1-Hashwert automatisch auswählen"
-#: gitk:9398
+#: gitk:10354
msgid "Diff display options"
-msgstr "Anzeige Vergleich"
+msgstr "Anzeige des Vergleichs"
-#: gitk:9400
+#: gitk:10356
msgid "Tab spacing"
msgstr "Tabulatorbreite"
-#: gitk:9404
+#: gitk:10359
msgid "Display nearby tags"
-msgstr "Naheliegende Ãœberschriften anzeigen"
+msgstr "Naheliegende Markierungen anzeigen"
-#: gitk:9409
+#: gitk:10362
msgid "Limit diffs to listed paths"
msgstr "Vergleich nur für angezeigte Pfade"
-#: gitk:9414
+#: gitk:10365
msgid "Support per-file encodings"
msgstr "Zeichenkodierung pro Datei ermitteln"
-#: gitk:9421
+#: gitk:10371 gitk:10436
msgid "External diff tool"
-msgstr "Externes Vergleich-(Diff-)Programm"
+msgstr "Externes Diff-Programm"
-#: gitk:9423
+#: gitk:10373
msgid "Choose..."
-msgstr "Wählen..."
+msgstr "Wählen ..."
-#: gitk:9428
+#: gitk:10378
msgid "Colors: press to choose"
msgstr "Farben: Klicken zum Wählen"
-#: gitk:9431
+#: gitk:10381
msgid "Background"
msgstr "Hintergrund"
-#: gitk:10153 gitk:10183
+#: gitk:10382 gitk:10412
msgid "background"
msgstr "Hintergrund"
-#: gitk:10156
+#: gitk:10385
msgid "Foreground"
msgstr "Vordergrund"
-#: gitk:10157
+#: gitk:10386
msgid "foreground"
msgstr "Vordergrund"
-#: gitk:10160
+#: gitk:10389
msgid "Diff: old lines"
msgstr "Vergleich: Alte Zeilen"
-#: gitk:10161
+#: gitk:10390
msgid "diff old lines"
msgstr "Vergleich - Alte Zeilen"
-#: gitk:10165
+#: gitk:10394
msgid "Diff: new lines"
msgstr "Vergleich: Neue Zeilen"
-#: gitk:10166
+#: gitk:10395
msgid "diff new lines"
msgstr "Vergleich - Neue Zeilen"
-#: gitk:10170
+#: gitk:10399
msgid "Diff: hunk header"
msgstr "Vergleich: Änderungstitel"
-#: gitk:10172
+#: gitk:10401
msgid "diff hunk header"
msgstr "Vergleich - Änderungstitel"
-#: gitk:10176
+#: gitk:10405
msgid "Marked line bg"
-msgstr "Markierte Zeile Hintergrund"
+msgstr "Hintergrund für markierte Zeile"
-#: gitk:10178
+#: gitk:10407
msgid "marked line background"
-msgstr "markierte Zeile Hintergrund"
+msgstr "Hintergrund für markierte Zeile"
-#: gitk:10182
+#: gitk:10411
msgid "Select bg"
-msgstr "Hintergrundfarbe Auswählen"
+msgstr "Hintergrundfarbe auswählen"
-#: gitk:9459
+#: gitk:10415
msgid "Fonts: press to choose"
msgstr "Schriftart: Klicken zum Wählen"
-#: gitk:9461
+#: gitk:10417
msgid "Main font"
msgstr "Programmschriftart"
-#: gitk:9462
+#: gitk:10418
msgid "Diff display font"
-msgstr "Vergleich"
+msgstr "Schriftart für Vergleich"
-#: gitk:9463
+#: gitk:10419
msgid "User interface font"
msgstr "Beschriftungen"
-#: gitk:9488
+#: gitk:10446
#, tcl-format
msgid "Gitk: choose color for %s"
msgstr "Gitk: Farbe wählen für %s"
-#: gitk:9934
+#: gitk:10893
msgid ""
"Sorry, gitk cannot run with this version of Tcl/Tk.\n"
" Gitk requires at least Tcl/Tk 8.4."
"Gitk läuft nicht mit dieser Version von Tcl/Tk.\n"
"Gitk benötigt mindestens Tcl/Tk 8.4."
-#: gitk:10047
+#: gitk:11020
msgid "Cannot find a git repository here."
msgstr "Kein Git-Projektarchiv gefunden."
-#: gitk:10051
+#: gitk:11024
#, tcl-format
msgid "Cannot find the git directory \"%s\"."
msgstr "Git-Verzeichnis »%s« wurde nicht gefunden."
-#: gitk:10098
+#: gitk:11071
#, tcl-format
msgid "Ambiguous argument '%s': both revision and filename"
msgstr "Mehrdeutige Angabe »%s«: Sowohl Version als auch Dateiname existiert."
-#: gitk:10110
+#: gitk:11083
msgid "Bad arguments to gitk:"
msgstr "Falsche Kommandozeilen-Parameter für gitk:"
-#: gitk:10170
+#: gitk:11167
msgid "Command line"
msgstr "Kommandozeile"
DocumentRoot /var/www/gitweb
- AliasMatch ^(/.*?)(\.git)(/.*)? /pub/git$1$3
+ AliasMatch ^(/.*?)(\.git)(/.*)?$ /pub/git$1$3
<Directory /var/www/gitweb>
Options ExecCGI
AddHandler cgi-script cgi
will provide human-friendly gitweb access.
+This solution is not 100% bulletproof, in the sense that if some project
+has a named ref (branch, tag) starting with 'git/', then paths such as
+
+http://git.example.com/project/command/abranch..git/abranch
+
+will fail with a 404 error.
+
+
Originally written by:
Kay Sievers <kay.sievers@vrfy.org>
return 0;
}
-void run_request_queue(void)
+static void run_request_queue(void)
{
#ifdef USE_CURL_MULTI
is_running_queue = 1;
static int curl_ssl_verify = -1;
static const char *ssl_cert;
-#if LIBCURL_VERSION_NUM >= 0x070902
+#if LIBCURL_VERSION_NUM >= 0x070903
static const char *ssl_key;
#endif
#if LIBCURL_VERSION_NUM >= 0x070908
}
if (!strcmp("http.sslcert", var))
return git_config_string(&ssl_cert, var, value);
-#if LIBCURL_VERSION_NUM >= 0x070902
+#if LIBCURL_VERSION_NUM >= 0x070903
if (!strcmp("http.sslkey", var))
return git_config_string(&ssl_key, var, value);
#endif
if (ssl_cert != NULL)
curl_easy_setopt(result, CURLOPT_SSLCERT, ssl_cert);
-#if LIBCURL_VERSION_NUM >= 0x070902
+#if LIBCURL_VERSION_NUM >= 0x070903
if (ssl_key != NULL)
curl_easy_setopt(result, CURLOPT_SSLKEY, ssl_key);
#endif
curl_ssl_verify = 0;
set_from_env(&ssl_cert, "GIT_SSL_CERT");
-#if LIBCURL_VERSION_NUM >= 0x070902
+#if LIBCURL_VERSION_NUM >= 0x070903
set_from_env(&ssl_key, "GIT_SSL_KEY");
#endif
#if LIBCURL_VERSION_NUM >= 0x070908
#ifndef NO_OPENSSL
static void ssl_socket_perror(const char *func)
{
- fprintf(stderr, "%s: %s\n", func, ERR_error_string(ERR_get_error(), 0));
+ fprintf(stderr, "%s: %s\n", func, ERR_error_string(ERR_get_error(), NULL));
}
#endif
static void *unpack_raw_entry(struct object_entry *obj, union delta_base *delta_base)
{
- unsigned char *p, c;
- unsigned long size;
+ unsigned char *p;
+ unsigned long size, c;
off_t base_offset;
unsigned shift;
void *data;
p = fill(1);
c = *p;
use(1);
- size += (c & 0x7fUL) << shift;
+ size += (c & 0x7f) << shift;
shift += 7;
}
obj->size = size;
die("invalid %s", typename(type));
if (fsck_object(obj, 1, fsck_error_function))
die("Error in object");
- if (fsck_walk(obj, mark_link, 0))
+ if (fsck_walk(obj, mark_link, NULL))
die("Not all child objects of %s are reachable", sha1_to_hex(obj->sha1));
if (obj->type == OBJ_TREE) {
if (!strcmp(var, "merge.default")) {
if (value)
- default_ll_merge = strdup(value);
+ default_ll_merge = xstrdup(value);
return 0;
}
if (!strcmp("name", ep)) {
if (!value)
return error("%s: lacks value", var);
- fn->description = strdup(value);
+ fn->description = xstrdup(value);
return 0;
}
* file named by %A, and signal that it has done with zero exit
* status.
*/
- fn->cmdline = strdup(value);
+ fn->cmdline = xstrdup(value);
return 0;
}
if (!strcmp("recursive", ep)) {
if (!value)
return error("%s: lacks value", var);
- fn->recursive = strdup(value);
+ fn->recursive = xstrdup(value);
return 0;
}
}
/*
- * If use_terminator is set, add a newline at the end of the entry.
+ * If use_terminator is set, we already handled any record termination
+ * at the end of the last record.
* Otherwise, add a diffopt.line_termination character before all
* entries but the first. (IOW, as a separator between entries)
*/
char **email, int allow_empty_email)
{
char *left, *right, *nstart, *nend;
- *name = *email = 0;
+ *name = *email = NULL;
if ((left = strchr(buffer, '<')) == NULL)
return NULL;
if (f == NULL)
return 1;
while (fgets(buffer, sizeof(buffer), f) != NULL) {
- char *name1 = 0, *email1 = 0, *name2 = 0, *email2 = 0;
+ char *name1 = NULL, *email1 = NULL, *name2 = NULL, *email2 = NULL;
if (buffer[0] == '#') {
static const char abbrev[] = "# repo-abbrev:";
int abblen = sizeof(abbrev) - 1;
if (!p) {
/* email passed in might not be wrapped in <>, but end with a \0 */
p = memchr(email, '\0', maxlen_email);
- if (p == 0)
+ if (!p)
return 0;
}
if (p - email + 1 < sizeof(buf))
* A virtual commit has (const char *)commit->util set to the name.
*/
-struct commit *make_virtual_commit(struct tree *tree, const char *comment)
+static struct commit *make_virtual_commit(struct tree *tree, const char *comment)
{
struct commit *commit = xcalloc(1, sizeof(struct commit));
commit->tree = tree;
static int usage_argh(const struct option *opts)
{
const char *s;
- int literal = opts->flags & PARSE_OPT_LITERAL_ARGHELP;
+ int literal = (opts->flags & PARSE_OPT_LITERAL_ARGHELP) || !opts->argh;
if (opts->flags & PARSE_OPT_OPTARG)
if (opts->long_name)
s = literal ? "[=%s]" : "[=<%s>]";
s = literal ? "[%s]" : "[<%s>]";
else
s = literal ? " %s" : " <%s>";
- return fprintf(stderr, s, opts->argh);
+ return fprintf(stderr, s, opts->argh ? opts->argh : "...");
}
#define USAGE_OPTS_WIDTH 24
#define USAGE_GAP 2
-int usage_with_options_internal(const char * const *usagestr,
+static int usage_with_options_internal(const char * const *usagestr,
const struct option *opts, int full)
{
if (!usagestr)
if (opts->type == OPTION_NUMBER)
pos += fprintf(stderr, "-NUM");
- switch (opts->type) {
- case OPTION_ARGUMENT:
- break;
- case OPTION_INTEGER:
- if (opts->flags & PARSE_OPT_OPTARG)
- if (opts->long_name)
- pos += fprintf(stderr, "[=<n>]");
- else
- pos += fprintf(stderr, "[<n>]");
- else
- pos += fprintf(stderr, " <n>");
- break;
- case OPTION_CALLBACK:
- if (opts->flags & PARSE_OPT_NOARG)
- break;
- /* FALLTHROUGH */
- case OPTION_FILENAME:
- /* FALLTHROUGH */
- case OPTION_STRING:
- if (opts->argh)
- pos += usage_argh(opts);
- else {
- if (opts->flags & PARSE_OPT_OPTARG)
- if (opts->long_name)
- pos += fprintf(stderr, "[=...]");
- else
- pos += fprintf(stderr, "[...]");
- else
- pos += fprintf(stderr, " ...");
- }
- break;
- default: /* OPTION_{BIT,BOOLEAN,NUMBER,SET_INT,SET_PTR} */
- break;
- }
+ if (!(opts->flags & PARSE_OPT_NOARG))
+ pos += usage_argh(opts);
if (pos <= USAGE_OPTS_WIDTH)
pad = USAGE_OPTS_WIDTH - pos;
* `flags`::
* mask of parse_opt_option_flags.
* PARSE_OPT_OPTARG: says that the argument is optional (not for BOOLEANs)
- * PARSE_OPT_NOARG: says that this option takes no argument, for CALLBACKs
+ * PARSE_OPT_NOARG: says that this option takes no argument
* PARSE_OPT_NONEG: says that this option cannot be negated
* PARSE_OPT_HIDDEN: this option is skipped in the default usage, and
* shown only in the full usage.
};
#define OPT_END() { OPTION_END }
-#define OPT_ARGUMENT(l, h) { OPTION_ARGUMENT, 0, (l), NULL, NULL, (h) }
+#define OPT_ARGUMENT(l, h) { OPTION_ARGUMENT, 0, (l), NULL, NULL, \
+ (h), PARSE_OPT_NOARG}
#define OPT_GROUP(h) { OPTION_GROUP, 0, NULL, NULL, NULL, (h) }
-#define OPT_BIT(s, l, v, h, b) { OPTION_BIT, (s), (l), (v), NULL, (h), 0, NULL, (b) }
-#define OPT_NEGBIT(s, l, v, h, b) { OPTION_NEGBIT, (s), (l), (v), NULL, (h), 0, NULL, (b) }
-#define OPT_BOOLEAN(s, l, v, h) { OPTION_BOOLEAN, (s), (l), (v), NULL, (h) }
-#define OPT_SET_INT(s, l, v, h, i) { OPTION_SET_INT, (s), (l), (v), NULL, (h), 0, NULL, (i) }
-#define OPT_SET_PTR(s, l, v, h, p) { OPTION_SET_PTR, (s), (l), (v), NULL, (h), 0, NULL, (p) }
-#define OPT_INTEGER(s, l, v, h) { OPTION_INTEGER, (s), (l), (v), NULL, (h) }
+#define OPT_BIT(s, l, v, h, b) { OPTION_BIT, (s), (l), (v), NULL, (h), \
+ PARSE_OPT_NOARG, NULL, (b) }
+#define OPT_NEGBIT(s, l, v, h, b) { OPTION_NEGBIT, (s), (l), (v), NULL, \
+ (h), PARSE_OPT_NOARG, NULL, (b) }
+#define OPT_BOOLEAN(s, l, v, h) { OPTION_BOOLEAN, (s), (l), (v), NULL, \
+ (h), PARSE_OPT_NOARG }
+#define OPT_SET_INT(s, l, v, h, i) { OPTION_SET_INT, (s), (l), (v), NULL, \
+ (h), PARSE_OPT_NOARG, NULL, (i) }
+#define OPT_SET_PTR(s, l, v, h, p) { OPTION_SET_PTR, (s), (l), (v), NULL, \
+ (h), PARSE_OPT_NOARG, NULL, (p) }
+#define OPT_INTEGER(s, l, v, h) { OPTION_INTEGER, (s), (l), (v), "n", (h) }
#define OPT_STRING(s, l, v, a, h) { OPTION_STRING, (s), (l), (v), (a), (h) }
#define OPT_DATE(s, l, v, h) \
{ OPTION_CALLBACK, (s), (l), (v), "time",(h), 0, \
if (cmd & 0x01) cp_off = *data++;
if (cmd & 0x02) cp_off |= (*data++ << 8);
if (cmd & 0x04) cp_off |= (*data++ << 16);
- if (cmd & 0x08) cp_off |= (*data++ << 24);
+ if (cmd & 0x08) cp_off |= ((unsigned) *data++ << 24);
if (cmd & 0x10) cp_size = *data++;
if (cmd & 0x20) cp_size |= (*data++ << 8);
if (cmd & 0x40) cp_size |= (*data++ << 16);
fputc(terminator, fp);
}
-extern void write_name_quotedpfx(const char *pfx, size_t pfxlen,
- const char *name, FILE *fp, int terminator)
+void write_name_quotedpfx(const char *pfx, size_t pfxlen,
+ const char *name, FILE *fp, int terminator)
{
int needquote = 0;
add_url(remote, alias_url(url));
}
+static void add_pushurl(struct remote *remote, const char *pushurl)
+{
+ ALLOC_GROW(remote->pushurl, remote->pushurl_nr + 1, remote->pushurl_alloc);
+ remote->pushurl[remote->pushurl_nr++] = pushurl;
+}
+
static struct remote *make_remote(const char *name, int len)
{
struct remote *ret;
strbuf_addstr(&branch, "HEAD:");
}
add_url_alias(remote, p);
- add_fetch_refspec(remote, strbuf_detach(&branch, 0));
+ add_fetch_refspec(remote, strbuf_detach(&branch, NULL));
/*
* Cogito compatible push: push current HEAD to remote #branch
* (master if missing)
strbuf_addf(&branch, ":refs/heads/%s", frag);
else
strbuf_addstr(&branch, ":refs/heads/master");
- add_push_refspec(remote, strbuf_detach(&branch, 0));
+ add_push_refspec(remote, strbuf_detach(&branch, NULL));
remote->fetch_tags = 1; /* always auto-follow */
}
if (git_config_string(&v, key, value))
return -1;
add_url(remote, v);
+ } else if (!strcmp(subkey, ".pushurl")) {
+ const char *v;
+ if (git_config_string(&v, key, value))
+ return -1;
+ add_pushurl(remote, v);
} else if (!strcmp(subkey, ".push")) {
const char *v;
if (git_config_string(&v, key, value))
for (j = 0; j < remotes[i]->url_nr; j++) {
remotes[i]->url[j] = alias_url(remotes[i]->url[j]);
}
+ for (j = 0; j < remotes[i]->pushurl_nr; j++) {
+ remotes[i]->pushurl[j] = alias_url(remotes[i]->pushurl[j]);
+ }
}
}
int send_all = flags & MATCH_REFS_ALL;
int send_mirror = flags & MATCH_REFS_MIRROR;
int errs;
- static const char *default_refspec[] = { ":", 0 };
+ static const char *default_refspec[] = { ":", NULL };
struct ref **dst_tail = tail_ref(dst);
if (!nr_refspec) {
int url_nr;
int url_alloc;
+ const char **pushurl;
+ int pushurl_nr;
+ int pushurl_alloc;
+
const char **push_refspec;
struct refspec *push;
int push_refspec_nr;
revs->show_all = 1;
} else if (!strcmp(arg, "--remove-empty")) {
revs->remove_empty_trees = 1;
+ } else if (!strcmp(arg, "--merges")) {
+ revs->merges_only = 1;
} else if (!strcmp(arg, "--no-merges")) {
revs->no_merges = 1;
} else if (!strcmp(arg, "--boundary")) {
return commit_ignore;
if (revs->no_merges && commit->parents && commit->parents->next)
return commit_ignore;
+ if (revs->merges_only && !(commit->parents && commit->parents->next))
+ return commit_ignore;
if (!commit_match(commit, revs))
return commit_ignore;
if (revs->prune && revs->dense) {
unsigned int dense:1,
prune:1,
no_merges:1,
+ merges_only:1,
no_walk:1,
show_all:1,
remove_empty_trees:1,
unsigned long len, enum object_type *type, unsigned long *sizep)
{
unsigned shift;
- unsigned char c;
- unsigned long size;
+ unsigned long size, c;
unsigned long used = 0;
c = buf[used++];
res = fread(sb->buf + sb->len, 1, size, f);
if (res > 0)
strbuf_setlen(sb, sb->len + res);
- else if (res < 0 && oldalloc == 0)
+ else if (oldalloc == 0)
strbuf_release(sb);
return res;
}
'
-test_expect_code 1 'cherry-pick an empty commit' '
-
- git checkout master &&
- git cherry-pick empty-branch
-
+test_expect_success 'cherry-pick an empty commit' '
+ git checkout master && {
+ git cherry-pick empty-branch
+ test "$?" = 1
+ }
'
test_expect_success 'index lockfile was removed' '
test_must_fail git add --verbose . &&
! ( git ls-files foo1 | grep foo1 )
'
+rm -f foo2
+
+test_expect_success POSIXPERM '--no-ignore-errors overrides config' '
+ git config add.ignore-errors 1 &&
+ git reset --hard &&
+ date >foo1 &&
+ date >foo2 &&
+ chmod 0 foo2 &&
+ test_must_fail git add --verbose --no-ignore-errors . &&
+ ! ( git ls-files foo1 | grep foo1 ) &&
+ git config add.ignore-errors 0
+'
+rm -f foo2
test_expect_success BSLASHPSPEC "git add 'fo\\[ou\\]bar' ignores foobar" '
git reset --hard &&
. ./test-lib.sh
. "$TEST_DIRECTORY"/diff-lib.sh ;# test-lib chdir's into trash
-test_expect_success \
- 'prepare reference tree' \
- 'mkdir path0 path1 &&
- cp "$TEST_DIRECTORY"/../COPYING path0/COPYING &&
- git update-index --add path0/COPYING &&
- tree=$(git write-tree) &&
- echo $tree'
-
-test_expect_success \
- 'prepare work tree' \
- 'cp path0/COPYING path1/COPYING &&
- git update-index --add --remove path0/COPYING path1/COPYING'
+test_expect_success 'prepare reference tree' '
+ mkdir path0 path1 &&
+ cp "$TEST_DIRECTORY"/../COPYING path0/COPYING &&
+ git update-index --add path0/COPYING &&
+ tree=$(git write-tree) &&
+ echo $tree
+'
+
+test_expect_success 'prepare work tree' '
+ cp path0/COPYING path1/COPYING &&
+ git update-index --add --remove path0/COPYING path1/COPYING
+'
# In the tree, there is only path0/COPYING. In the cache, path0 and
# path1 both have COPYING and the latter is a copy of path0/COPYING.
# Comparing the full tree with cache should tell us so.
-git diff-index -C --find-copies-harder $tree >current
-
cat >expected <<\EOF
:100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 6ff87c4664981e4397625791c8ea3bbb5f2279a3 C100 path0/COPYING path1/COPYING
EOF
-test_expect_success \
- 'validate the result (#1)' \
- 'compare_diff_raw current expected'
+test_expect_success 'copy detection' '
+ git diff-index -C --find-copies-harder $tree >current &&
+ compare_diff_raw current expected
+'
+
+test_expect_success 'copy detection, cached' '
+ git diff-index -C --find-copies-harder --cached $tree >current &&
+ compare_diff_raw current expected
+'
# In the tree, there is only path0/COPYING. In the cache, path0 and
# path1 both have COPYING and the latter is a copy of path0/COPYING.
# path1/COPYING suddenly appearing from nowhere, not detected as
# a copy from path0/COPYING.
-git diff-index -C $tree path1 >current
-
cat >expected <<\EOF
:000000 100644 0000000000000000000000000000000000000000 6ff87c4664981e4397625791c8ea3bbb5f2279a3 A path1/COPYING
EOF
-test_expect_success \
- 'validate the result (#2)' \
- 'compare_diff_raw current expected'
-
-test_expect_success \
- 'tweak work tree' \
- 'rm -f path0/COPYING &&
- git update-index --remove path0/COPYING'
+test_expect_success 'copy, limited to a subtree' '
+ git diff-index -C --find-copies-harder $tree path1 >current &&
+ compare_diff_raw current expected
+'
+test_expect_success 'tweak work tree' '
+ rm -f path0/COPYING &&
+ git update-index --remove path0/COPYING
+'
# In the tree, there is only path0/COPYING. In the cache, path0 does
# not have COPYING anymore and path1 has COPYING which is a copy of
# path0/COPYING. Showing the full tree with cache should tell us about
# the rename.
-git diff-index -C $tree >current
-
cat >expected <<\EOF
:100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 6ff87c4664981e4397625791c8ea3bbb5f2279a3 R100 path0/COPYING path1/COPYING
EOF
-test_expect_success \
- 'validate the result (#3)' \
- 'compare_diff_raw current expected'
+test_expect_success 'rename detection' '
+ git diff-index -C --find-copies-harder $tree >current &&
+ compare_diff_raw current expected
+'
# In the tree, there is only path0/COPYING. In the cache, path0 does
# not have COPYING anymore and path1 has COPYING which is a copy of
# path0/COPYING. When we say we care only about path1, we should just
# see path1/COPYING appearing from nowhere.
-git diff-index -C $tree path1 >current
-
cat >expected <<\EOF
:000000 100644 0000000000000000000000000000000000000000 6ff87c4664981e4397625791c8ea3bbb5f2279a3 A path1/COPYING
EOF
-test_expect_success \
- 'validate the result (#4)' \
- 'compare_diff_raw current expected'
+test_expect_success 'rename, limited to a subtree' '
+ git diff-index -C --find-copies-harder $tree path1 >current &&
+ compare_diff_raw current expected
+'
test_done
--- /dev/null
+#!/bin/sh
+
+test_description='diff -r -t shows directory additions and deletions'
+
+. ./test-lib.sh
+
+test_expect_success setup '
+ mkdir dc dr dt &&
+ >dc/1 &&
+ >dr/2 &&
+ >dt/3 &&
+ >fc &&
+ >fr &&
+ >ft &&
+ git add . &&
+ test_tick &&
+ git commit -m initial &&
+
+ rm -fr dt dr ft fr &&
+ mkdir da ft &&
+ for p in dc/1 da/4 dt ft/5 fc
+ do
+ echo hello >$p || exit
+ done &&
+ git add -u &&
+ git add . &&
+ test_tick &&
+ git commit -m second
+'
+
+cat >expect <<\EOF
+A da
+A da/4
+M dc
+M dc/1
+D dr
+D dr/2
+A dt
+D dt
+D dt/3
+M fc
+D fr
+D ft
+A ft
+A ft/5
+EOF
+
+test_expect_success verify '
+ git diff-tree -r -t --name-status HEAD^ HEAD >actual &&
+ test_cmp expect actual
+'
+
+test_done
'git archive --output=b4.tar HEAD &&
test_cmp b.tar b4.tar'
+test_expect_success 'git archive --remote' \
+ 'git archive --remote=. HEAD >b5.tar &&
+ test_cmp b.tar b5.tar'
+
test_expect_success \
'validate file modification time' \
'mkdir extract &&
cat > test/expect << EOF
* remote origin
- URL: $(pwd)/one
+ Fetch URL: $(pwd)/one
+ Push URL: $(pwd)/one
HEAD branch: master
Remote branches:
master new (next fetch will store in remotes/origin)
master pushes to master (local out of date)
master pushes to upstream (create)
* remote two
- URL: ../two
+ Fetch URL: ../two
+ Push URL: ../three
HEAD branch (remote HEAD is ambiguous, may be one of the following):
another
master
git branch --track rebase origin/master &&
git branch -d -r origin/master &&
git config --add remote.two.url ../two &&
+ git config --add remote.two.pushurl ../three &&
git config branch.rebase.rebase true &&
git config branch.octopus.merge "topic-a topic-b topic-c" &&
(cd ../one &&
cat > test/expect << EOF
* remote origin
- URL: $(pwd)/one
+ Fetch URL: $(pwd)/one
+ Push URL: $(pwd)/one
HEAD branch: (not queried)
Remote branches: (status not queried)
master
git config --remove-section remote.there
git config --remove-section branch.master
+test_expect_success 'push with config remote.*.pushurl' '
+
+ mk_test heads/master &&
+ git checkout master &&
+ git config remote.there.url test2repo &&
+ git config remote.there.pushurl testrepo &&
+ git push there &&
+ check_push_result $the_commit heads/master
+'
+
+# clean up the cruft left with the previous one
+git config --remove-section remote.there
+
test_expect_success 'push with dry-run' '
mk_test heads/master &&
git remote add -f me . &&
git checkout copy &&
+ git tag copy-orig &&
git reset --hard HEAD^ &&
echo conflicting modification > file &&
git commit -m conflict file &&
git checkout to-rebase &&
echo file > file2 &&
git commit -m to-rebase file2 &&
+ git tag to-rebase-orig &&
git pull --rebase me copy &&
test "conflicting modification" = "$(cat file)" &&
test file = $(cat file2)
'
+test_expect_success '--rebase with rebased default upstream' '
+
+ git update-ref refs/remotes/me/copy copy-orig &&
+ git checkout --track -b to-rebase2 me/copy &&
+ git reset --hard to-rebase-orig &&
+ git pull --rebase &&
+ test "conflicting modification" = "$(cat file)" &&
+ test file = $(cat file2)
+
+'
+
test_expect_success 'pull --rebase dies early with dirty working directory' '
+ git checkout to-rebase &&
git update-ref refs/remotes/me/copy copy^ &&
COPY=$(git rev-parse --verify me/copy) &&
git rebase --onto $COPY copy &&
done
+cat >expected <<EOF
+file:foo mmap bar_mmap
+EOF
+
+test_expect_success 'grep -e A --and -e B' '
+ git grep -e "foo mmap" --and -e bar_mmap >actual &&
+ test_cmp expected actual
+'
+
+cat >expected <<EOF
+file:foo_mmap bar mmap
+file:foo_mmap bar mmap baz
+EOF
+
+
+test_expect_success 'grep ( -e A --or -e B ) --and -e B' '
+ git grep \( -e foo_ --or -e baz \) \
+ --and -e " mmap" >actual &&
+ test_cmp expected actual
+'
+
+cat >expected <<EOF
+file:foo mmap bar
+EOF
+
+test_expect_success 'grep -e A --and --not -e B' '
+ git grep -e "foo mmap" --and --not -e bar_mmap >actual &&
+ test_cmp expected actual
+'
+
test_expect_success 'log grep setup' '
echo a >>file &&
test_tick &&
test_description='Test updating submodules
This test verifies that "git submodule update" detaches the HEAD of the
-submodule and "git submodule update --rebase" does not detach the HEAD.
+submodule and "git submodule update --rebase/--merge" does not detach the HEAD.
'
. ./test-lib.sh
)
'
+test_expect_success 'submodule update --merge staying on master' '
+ (cd super/submodule &&
+ git reset --hard HEAD~1
+ ) &&
+ (cd super &&
+ (cd submodule &&
+ compare_head
+ ) &&
+ git submodule update --merge submodule &&
+ cd submodule &&
+ compare_head
+ )
+'
+
test_expect_success 'submodule update - rebase in .git/config' '
(cd super &&
git config submodule.submodule.update rebase
)
'
+test_expect_success 'submodule update - merge in .git/config' '
+ (cd super &&
+ git config submodule.submodule.update merge
+ ) &&
+ (cd super/submodule &&
+ git reset --hard HEAD~1
+ ) &&
+ (cd super &&
+ (cd submodule &&
+ compare_head
+ ) &&
+ git submodule update submodule &&
+ cd submodule &&
+ compare_head
+ )
+'
+
+test_expect_success 'submodule update - checkout in .git/config but --merge given' '
+ (cd super &&
+ git config submodule.submodule.update checkout
+ ) &&
+ (cd super/submodule &&
+ git reset --hard HEAD~1
+ ) &&
+ (cd super &&
+ (cd submodule &&
+ compare_head
+ ) &&
+ git submodule update --merge submodule &&
+ cd submodule &&
+ compare_head
+ )
+'
+
test_expect_success 'submodule update - checkout in .git/config' '
(cd super &&
git config submodule.submodule.update checkout
)
'
+test_expect_success 'submodule init picks up merge' '
+ (cd super &&
+ git config submodule.merging.url git://non-existing/git &&
+ git config submodule.merging.path does-not-matter &&
+ git config submodule.merging.update merge &&
+ git submodule init merging &&
+ test "merge" = $(git config submodule.merging.update)
+ )
+'
+
test_done
grep "^To: to@example.com$" msgtxt1
'
+test_expect_success 'cccmd works' '
+ clean_fake_sendmail &&
+ cp $patches cccmd.patch &&
+ echo cccmd--cccmd@example.com >>cccmd.patch &&
+ {
+ echo "#!$SHELL_PATH"
+ echo sed -n -e s/^cccmd--//p \"\$1\"
+ } > cccmd-sed &&
+ chmod +x cccmd-sed &&
+ git send-email \
+ --from="Example <nobody@example.com>" \
+ --to=nobody@example.com \
+ --cc-cmd=./cccmd-sed \
+ --smtp-server="$(pwd)/fake.sendmail" \
+ cccmd.patch \
+ &&
+ grep ^Cc:.*cccmd@example.com msgtxt1
+'
+
z8=zzzzzzzz
z64=$z8$z8$z8$z8$z8$z8$z8$z8
z512=$z64$z64$z64$z64$z64$z64$z64$z64
test_suppression () {
git send-email \
--dry-run \
- --suppress-cc=$1 \
+ --suppress-cc=$1 ${2+"--suppress-cc=$2"} \
--from="Example <from@example.com>" \
--to=to@example.com \
--smtp-server relay.example.com \
sed -e "s/^\(Date:\).*/\1 DATE-STRING/" \
-e "s/^\(Message-Id:\).*/\1 MESSAGE-ID-STRING/" \
-e "s/^\(X-Mailer:\).*/\1 X-MAILER-STRING/" \
- >actual-suppress-$1 &&
- test_cmp expected-suppress-$1 actual-suppress-$1
+ >actual-suppress-$1${2+"-$2"} &&
+ test_cmp expected-suppress-$1${2+"-$2"} actual-suppress-$1${2+"-$2"}
}
test_expect_success 'sendemail.cc set' '
test_suppression sob
'
+cat >expected-suppress-cccmd <<\EOF
+0001-Second.patch
+(mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>'
+(mbox) Adding cc: One <one@example.com> from line 'Cc: One <one@example.com>, two@example.com'
+(mbox) Adding cc: two@example.com from line 'Cc: One <one@example.com>, two@example.com'
+(body) Adding cc: C O Mitter <committer@example.com> from line 'Signed-off-by: C O Mitter <committer@example.com>'
+Dry-OK. Log says:
+Server: relay.example.com
+MAIL FROM:<from@example.com>
+RCPT TO:<to@example.com>,<author@example.com>,<one@example.com>,<two@example.com>,<committer@example.com>
+From: Example <from@example.com>
+To: to@example.com
+Cc: A <author@example.com>, One <one@example.com>, two@example.com, C O Mitter <committer@example.com>
+Subject: [PATCH 1/1] Second.
+Date: DATE-STRING
+Message-Id: MESSAGE-ID-STRING
+X-Mailer: X-MAILER-STRING
+
+Result: OK
+EOF
+
+test_expect_success 'sendemail.cccmd' '
+ echo echo cc-cmd@example.com > cccmd &&
+ chmod +x cccmd &&
+ git config sendemail.cccmd ./cccmd &&
+ test_suppression cccmd
+'
+
cat >expected-suppress-all <<\EOF
0001-Second.patch
Dry-OK. Log says:
(mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>'
(mbox) Adding cc: One <one@example.com> from line 'Cc: One <one@example.com>, two@example.com'
(mbox) Adding cc: two@example.com from line 'Cc: One <one@example.com>, two@example.com'
+(cc-cmd) Adding cc: cc-cmd@example.com from: './cccmd'
Dry-OK. Log says:
Server: relay.example.com
MAIL FROM:<from@example.com>
-RCPT TO:<to@example.com>,<author@example.com>,<one@example.com>,<two@example.com>
+RCPT TO:<to@example.com>,<author@example.com>,<one@example.com>,<two@example.com>,<cc-cmd@example.com>
From: Example <from@example.com>
To: to@example.com
-Cc: A <author@example.com>, One <one@example.com>, two@example.com
+Cc: A <author@example.com>, One <one@example.com>, two@example.com, cc-cmd@example.com
Subject: [PATCH 1/1] Second.
Date: DATE-STRING
Message-Id: MESSAGE-ID-STRING
test_suppression body
'
+cat >expected-suppress-body-cccmd <<\EOF
+0001-Second.patch
+(mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>'
+(mbox) Adding cc: One <one@example.com> from line 'Cc: One <one@example.com>, two@example.com'
+(mbox) Adding cc: two@example.com from line 'Cc: One <one@example.com>, two@example.com'
+Dry-OK. Log says:
+Server: relay.example.com
+MAIL FROM:<from@example.com>
+RCPT TO:<to@example.com>,<author@example.com>,<one@example.com>,<two@example.com>
+From: Example <from@example.com>
+To: to@example.com
+Cc: A <author@example.com>, One <one@example.com>, two@example.com
+Subject: [PATCH 1/1] Second.
+Date: DATE-STRING
+Message-Id: MESSAGE-ID-STRING
+X-Mailer: X-MAILER-STRING
+
+Result: OK
+EOF
+
+test_expect_success '--suppress-cc=body --suppress-cc=cccmd' '
+ test_suppression body cccmd
+'
+
cat >expected-suppress-sob <<\EOF
0001-Second.patch
(mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>'
EOF
test_expect_success '--suppress-cc=sob' '
+ git config --unset sendemail.cccmd
test_suppression sob
'
"^:refs/${remotes_git_svn}$"
'
+test_expect_success 'dcommit $rev does not clobber current branch' '
+ git svn fetch -i bar &&
+ git checkout -b my-bar refs/remotes/bar &&
+ echo 1 > foo &&
+ git add foo &&
+ git commit -m "change 1" &&
+ echo 2 > foo &&
+ git add foo &&
+ git commit -m "change 2" &&
+ old_head=$(git rev-parse HEAD) &&
+ git svn dcommit -i bar HEAD^ &&
+ test $old_head = $(git rev-parse HEAD) &&
+ test refs/heads/my-bar = $(git symbolic-ref HEAD) &&
+ git log refs/remotes/bar | grep "change 1" &&
+ ! git log refs/remotes/bar | grep "change 2" &&
+ git checkout master &&
+ git branch -D my-bar
+ '
+
test_expect_success 'able to dcommit to a subdirectory' "
git svn fetch -i bar &&
git checkout -b my-bar refs/remotes/bar &&
--- /dev/null
+#!/bin/sh
+#
+# Copyright (c) 2009 Marc Branchaud
+#
+
+test_description='git svn multiple branch and tag paths in the svn repo'
+. ./lib-git-svn.sh
+
+test_expect_success 'setup svnrepo' '
+ mkdir project \
+ project/trunk \
+ project/b_one \
+ project/b_two \
+ project/tags_A \
+ project/tags_B &&
+ echo 1 > project/trunk/a.file &&
+ svn_cmd import -m "$test_description" project "$svnrepo/project" &&
+ rm -rf project &&
+ svn_cmd cp -m "Branch 1" "$svnrepo/project/trunk" \
+ "$svnrepo/project/b_one/first" &&
+ svn_cmd cp -m "Tag 1" "$svnrepo/project/trunk" \
+ "$svnrepo/project/tags_A/1.0" &&
+ svn_cmd co "$svnrepo/project" svn_project &&
+ ( cd svn_project &&
+ echo 2 > trunk/a.file &&
+ svn_cmd ci -m "Change 1" trunk/a.file &&
+ svn_cmd cp -m "Branch 2" "$svnrepo/project/trunk" \
+ "$svnrepo/project/b_one/second" &&
+ svn_cmd cp -m "Tag 2" "$svnrepo/project/trunk" \
+ "$svnrepo/project/tags_A/2.0" &&
+ echo 3 > trunk/a.file &&
+ svn_cmd ci -m "Change 2" trunk/a.file &&
+ svn_cmd cp -m "Branch 3" "$svnrepo/project/trunk" \
+ "$svnrepo/project/b_two/1" &&
+ svn_cmd cp -m "Tag 3" "$svnrepo/project/trunk" \
+ "$svnrepo/project/tags_A/3.0" &&
+ echo 4 > trunk/a.file &&
+ svn_cmd ci -m "Change 3" trunk/a.file &&
+ svn_cmd cp -m "Branch 4" "$svnrepo/project/trunk" \
+ "$svnrepo/project/b_two/2" &&
+ svn_cmd cp -m "Tag 4" "$svnrepo/project/trunk" \
+ "$svnrepo/project/tags_A/4.0" &&
+ svn_cmd up &&
+ echo 5 > b_one/first/a.file &&
+ svn_cmd ci -m "Change 4" b_one/first/a.file &&
+ svn_cmd cp -m "Tag 5" "$svnrepo/project/b_one/first" \
+ "$svnrepo/project/tags_B/v5" &&
+ echo 6 > b_one/second/a.file &&
+ svn_cmd ci -m "Change 5" b_one/second/a.file &&
+ svn_cmd cp -m "Tag 6" "$svnrepo/project/b_one/second" \
+ "$svnrepo/project/tags_B/v6" &&
+ echo 7 > b_two/1/a.file &&
+ svn_cmd ci -m "Change 6" b_two/1/a.file &&
+ svn_cmd cp -m "Tag 7" "$svnrepo/project/b_two/1" \
+ "$svnrepo/project/tags_B/v7" &&
+ echo 8 > b_two/2/a.file &&
+ svn_cmd ci -m "Change 7" b_two/2/a.file &&
+ svn_cmd cp -m "Tag 8" "$svnrepo/project/b_two/2" \
+ "$svnrepo/project/tags_B/v8"
+ )
+'
+
+test_expect_success 'clone multiple branch and tag paths' '
+ git svn clone -T trunk \
+ -b b_one/* --branches b_two/* \
+ -t tags_A/* --tags tags_B \
+ "$svnrepo/project" git_project &&
+ ( cd git_project &&
+ git rev-parse refs/remotes/first &&
+ git rev-parse refs/remotes/second &&
+ git rev-parse refs/remotes/1 &&
+ git rev-parse refs/remotes/2 &&
+ git rev-parse refs/remotes/tags/1.0 &&
+ git rev-parse refs/remotes/tags/2.0 &&
+ git rev-parse refs/remotes/tags/3.0 &&
+ git rev-parse refs/remotes/tags/4.0 &&
+ git rev-parse refs/remotes/tags/v5 &&
+ git rev-parse refs/remotes/tags/v6 &&
+ git rev-parse refs/remotes/tags/v7 &&
+ git rev-parse refs/remotes/tags/v8
+ )
+'
+
+test_expect_success 'Multiple branch or tag paths require -d' '
+ ( cd git_project &&
+ test_must_fail git svn branch -m "No new branch" Nope &&
+ test_must_fail git svn tag -m "No new tag" Tagless &&
+ test_must_fail git rev-parse refs/remotes/Nope &&
+ test_must_fail git rev-parse refs/remotes/tags/Tagless
+ ) &&
+ ( cd svn_project &&
+ svn_cmd up &&
+ test_must_fail test -d b_one/Nope &&
+ test_must_fail test -d b_two/Nope &&
+ test_must_fail test -d tags_A/Tagless &&
+ test_must_fail test -d tags_B/Tagless
+ )
+'
+
+test_expect_success 'create new branches and tags' '
+ ( cd git_project &&
+ git svn branch -m "New branch 1" -d project/b_one New1 ) &&
+ ( cd svn_project &&
+ svn_cmd up && test -e b_one/New1/a.file ) &&
+
+ ( cd git_project &&
+ git svn branch -m "New branch 2" -d project/b_two New2 ) &&
+ ( cd svn_project &&
+ svn_cmd up && test -e b_two/New2/a.file ) &&
+
+ ( cd git_project &&
+ git svn branch -t -m "New tag 1" -d project/tags_A Tag1 ) &&
+ ( cd svn_project &&
+ svn_cmd up && test -e tags_A/Tag1/a.file ) &&
+
+ ( cd git_project &&
+ git svn tag -m "New tag 2" -d project/tags_B Tag2 ) &&
+ ( cd svn_project &&
+ svn_cmd up && test -e tags_B/Tag2/a.file )
+'
+
+test_done
--- /dev/null
+#!/bin/sh
+#
+# Copyright (c) 2009 Ben Jackson
+#
+
+test_description='git svn reset'
+. ./lib-git-svn.sh
+
+test_expect_success 'setup test repository' '
+ svn_cmd co "$svnrepo" s &&
+ (
+ cd s &&
+ mkdir vis &&
+ echo always visible > vis/vis.txt &&
+ svn_cmd add vis &&
+ svn_cmd commit -m "create visible files" &&
+ mkdir hid &&
+ echo initially hidden > hid/hid.txt &&
+ svn_cmd add hid &&
+ svn_cmd commit -m "create initially hidden files" &&
+ svn_cmd up &&
+ echo mod >> vis/vis.txt &&
+ svn_cmd commit -m "modify vis" &&
+ svn_cmd up
+ )
+'
+
+test_expect_success 'clone SVN repository with hidden directory' '
+ git svn init "$svnrepo" g &&
+ ( cd g && git svn fetch --ignore-paths="^hid" )
+'
+
+test_expect_success 'modify hidden file in SVN repo' '
+ ( cd s &&
+ echo mod hidden >> hid/hid.txt &&
+ svn_cmd commit -m "modify hid" &&
+ svn_cmd up
+ )
+'
+
+test_expect_success 'fetch fails on modified hidden file' '
+ ( cd g &&
+ git svn find-rev refs/remotes/git-svn > ../expect &&
+ ! git svn fetch 2> ../errors &&
+ git svn find-rev refs/remotes/git-svn > ../expect2 ) &&
+ fgrep "not found in commit" errors &&
+ test_cmp expect expect2
+'
+
+test_expect_success 'reset unwinds back to r1' '
+ ( cd g &&
+ git svn reset -r1 &&
+ git svn find-rev refs/remotes/git-svn > ../expect2 ) &&
+ echo 1 >expect &&
+ test_cmp expect expect2
+'
+
+test_expect_success 'refetch succeeds not ignoring any files' '
+ ( cd g &&
+ git svn fetch &&
+ git svn rebase &&
+ fgrep "mod hidden" hid/hid.txt
+ )
+'
+
+test_done
static char *string = NULL;
static char *file = NULL;
-int length_callback(const struct option *opt, const char *arg, int unset)
+static int length_callback(const struct option *opt, const char *arg, int unset)
{
printf("Callback: \"%s\", %d\n",
(arg ? arg : "not set"), unset);
return 0;
}
-int number_callback(const struct option *opt, const char *arg, int unset)
+static int number_callback(const struct option *opt, const char *arg, int unset)
{
*(int *)opt->value = strtol(arg, NULL, 10);
return 0;
if (!tree || type != OBJ_TREE)
die("corrupt tree sha %s", sha1_to_hex(sha1));
+ if (DIFF_OPT_TST(opt, TREE_IN_RECURSIVE)) {
+ newbase[baselen + pathlen] = 0;
+ opt->add_remove(opt, *prefix, mode, sha1, newbase);
+ newbase[baselen + pathlen] = '/';
+ }
+
init_tree_desc(&inner, tree, size);
show_tree(opt, prefix, &inner, newbase, baselen + 1 + pathlen);
return call_unpack_fn(src, o);
}
-int traverse_trees_recursive(int n, unsigned long dirmask, unsigned long df_conflicts, struct name_entry *names, struct traverse_info *info)
+static int traverse_trees_recursive(int n, unsigned long dirmask, unsigned long df_conflicts, struct name_entry *names, struct traverse_info *info)
{
int i;
struct tree_desc t[MAX_UNPACK_TREES];
if (src[0])
conflicts |= 1;
}
+
+ /* special case: "diff-index --cached" looking at a tree */
+ if (o->diff_index_cached &&
+ n == 1 && dirmask == 1 && S_ISDIR(names->mode)) {
+ int matches;
+ matches = cache_tree_matches_traversal(o->src_index->cache_tree,
+ names, info);
+ /*
+ * Everything under the name matches. Adjust o->pos to
+ * skip the entire hierarchy.
+ */
+ if (matches) {
+ o->pos += matches;
+ return mask;
+ }
+ }
+
if (traverse_trees_recursive(n, dirmask, conflicts,
names, info) < 0)
return -1;
aggressive:1,
skip_unmerged:1,
initial_checkout:1,
+ diff_index_cached:1,
gently:1;
const char *prefix;
int pos;
"[^<>= \t]+|[^[:space:]]|[\x80-\xff]+"),
PATTERNS("java",
"!^[ \t]*(catch|do|for|if|instanceof|new|return|switch|throw|while)\n"
- "^[ \t]*(([ \t]*[A-Za-z_][A-Za-z_0-9]*){2,}[ \t]*\\([^;]*)$",
+ "^[ \t]*(([A-Za-z_][A-Za-z_0-9]*[ \t]+)+[A-Za-z_][A-Za-z_0-9]*[ \t]*\\([^;]*)$",
+ /* -- */
"[a-zA-Z_][a-zA-Z0-9_]*"
"|[-+0-9.e]+[fFlL]?|0[xXbB]?[0-9a-fA-F]+[lL]?"
"|[-+*/<>%&^|=!]="
/* Objective-C methods */
"^[ \t]*([-+][ \t]*\\([ \t]*[A-Za-z_][A-Za-z_0-9* \t]*\\)[ \t]*[A-Za-z_].*)$\n"
/* C functions */
- "^[ \t]*(([ \t]*[A-Za-z_][A-Za-z_0-9]*){2,}[ \t]*\\([^;]*)$\n"
+ "^[ \t]*(([A-Za-z_][A-Za-z_0-9]*[ \t]+)+[A-Za-z_][A-Za-z_0-9]*[ \t]*\\([^;]*)$\n"
/* Objective-C class/protocol definitions */
"^(@(implementation|interface|protocol)[ \t].*)$",
/* -- */
static struct whitespace_rule {
const char *rule_name;
unsigned rule_bits;
+ unsigned loosens_error;
} whitespace_rule_names[] = {
- { "trailing-space", WS_TRAILING_SPACE },
- { "space-before-tab", WS_SPACE_BEFORE_TAB },
- { "indent-with-non-tab", WS_INDENT_WITH_NON_TAB },
- { "cr-at-eol", WS_CR_AT_EOL },
+ { "trailing-space", WS_TRAILING_SPACE, 0 },
+ { "space-before-tab", WS_SPACE_BEFORE_TAB, 0 },
+ { "indent-with-non-tab", WS_INDENT_WITH_NON_TAB, 0 },
+ { "cr-at-eol", WS_CR_AT_EOL, 1 },
};
unsigned parse_whitespace_rule(const char *string)
unsigned all_rule = 0;
int i;
for (i = 0; i < ARRAY_SIZE(whitespace_rule_names); i++)
- all_rule |= whitespace_rule_names[i].rule_bits;
+ if (!whitespace_rule_names[i].loosens_error)
+ all_rule |= whitespace_rule_names[i].rule_bits;
return all_rule;
} else if (ATTR_FALSE(value)) {
/* false (-whitespace) */
int wt_status_relative_paths = 1;
int wt_status_use_color = -1;
-int wt_status_submodule_summary;
+static int wt_status_submodule_summary;
static char wt_status_colors[][COLOR_MAXLEN] = {
GIT_COLOR_NORMAL, /* WT_STATUS_HEADER */
GIT_COLOR_GREEN, /* WT_STATUS_UPDATED */