git-diff
git-diff-files
git-diff-index
-git-diff-stages
git-diff-tree
git-describe
git-fast-import
git-request-pull
git-rerere
git-reset
-git-resolve
git-rev-list
git-rev-parse
git-revert
--- /dev/null
+GIT v1.5.1 Release Notes
+========================
+
+Updates since v1.5.0
+--------------------
+
+* Deprecated commands and options.
+
+ - git-diff-stages and git-resolve have been removed.
+
+* New commands and options.
+
+ - "git log" and friends take --reverse. This makes output
+ that typically goes reverse order in chronological order.
+ "git shortlog" usually lists commits in chronological order,
+ but with "--reverse", they are shown in reverse
+ chronological order.
+
+ - "git diff" learned --ignore-space-at-eol. This is a weaker
+ form of --ignore-space-change.
+
+ - "git name-rev" learned --refs=<pattern>, to limit the tags
+ used for naming the given revisions only to the ones
+ matching the given pattern.
+
+* Updated behaviour of existing commands.
+
+ - "git diff" outputs a trailing HT when pathnames have embedded
+ SP on +++/--- header lines, in order to help "GNU patch" to
+ parse its output. "git apply" was already updated to accept
+ this modified output format since ce74618d (Sep 22, 2006).
+
+* Hooks
+
+ - The sample update hook to show how to send out notification
+ e-mail was updated to show only new commits that appeared in
+ the repository. Earlier, it showed new commits that appeared
+ on the branch.
+
+--
+exec >/var/tmp/1
+O=v1.5.0-49-g69bc0e2
+echo O=`git describe master`
+git shortlog --no-merges $O..master ^maint
git-diff-files plumbinginterrogators
git-diff-index plumbinginterrogators
git-diff mainporcelain
-git-diff-stages plumbinginterrogators
git-diff-tree plumbinginterrogators
git-fast-import ancillarymanipulators
git-fetch mainporcelain
git-request-pull foreignscminterface
git-rerere ancillaryinterrogators
git-reset mainporcelain
-git-resolve mainporcelain
git-revert mainporcelain
git-rev-list plumbinginterrogators
git-rev-parse ancillaryinterrogators
The default set of "refspec" for gitlink:git-push[1]. See
gitlink:git-push[1].
+remote.<name>.skipDefaultUpdate::
+ If true, this remote will be skipped by default when updating
+ using the remote subcommand of gitlink:git-remote[1].
+
remote.<name>.receivepack::
The default program to execute on the remote side when pushing. See
option \--exec of gitlink:git-push[1].
The default program to execute on the remote side when fetching. See
option \--exec of gitlink:git-fetch-pack[1].
+remotes.<group>::
+ The list of remotes which are fetched by "git remote update
+ <group>". See gitlink:git-remote[1].
+
repack.usedeltabaseoffset::
Allow gitlink:git-repack[1] to create packs that uses
delta-base offset. Defaults to false.
git-merge-index git-merge-one-file hello.c
-and that is what higher level `git resolve` is implemented with.
+and that is what higher level `git merge -s resolve` is implemented
+with.
Now, let's pretend you are the one who did all the work in
`mybranch`, and the fruit of your hard work has finally been merged
to the `master` branch. Let's go back to `mybranch`, and run
-resolve to get the "upstream changes" back to your branch.
+`git merge` to get the "upstream changes" back to your branch.
------------
$ git checkout mybranch
----------------
Because your branch did not contain anything more than what are
-already merged into the `master` branch, the resolve operation did
+already merged into the `master` branch, the merge operation did
not actually do a merge. Instead, it just updated the top of
the tree of your branch to that of the `master` branch. This is
often called 'fast forward' merge.
usefulness when git Native and SSH transports were introduced,
and not used by `git pull` or `git push` scripts.
-Once you fetch from the remote repository, you `resolve` that
+Once you fetch from the remote repository, you `merge` that
with your current branch.
However -- it's such a common thing to `fetch` and then
-immediately `resolve`, that it's called `git pull`, and you can
+immediately `merge`, that it's called `git pull`, and you can
simply do
----------------
-a::
Shorthand for "--text".
+--ignore-space-at-eol::
+ Ignore changes in white spaces at EOL.
+
--ignore-space-change::
Ignore changes in amount of white space. This ignores white
space at line end, and consider all other sequences of one or
Introduction
------------
-The diff commands git-diff-index, git-diff-files, git-diff-tree, and
-git-diff-stages can be told to manipulate differences they find in
+The diff commands git-diff-index, git-diff-files, and git-diff-tree
+can be told to manipulate differences they find in
unconventional ways before showing diff(1) output. The manipulation
is collectively called "diffcore transformation". This short note
describes what they are and how to use them to produce diff outputs
- git-diff-tree compares contents of two "tree" objects;
- - git-diff-stages compares contents of blobs at two stages in an
- unmerged index file.
-
In all of these cases, the commands themselves compare
corresponding paths in the two sets of files. The result of
comparison is passed from these commands to what is internally
SYNOPSIS
--------
-'git-cvsexportcommit' [-h] [-v] [-c] [-P] [-p] [-a] [-f] [-m msgprefix] [PARENTCOMMIT] COMMITID
+'git-cvsexportcommit' [-h] [-v] [-c] [-P] [-p] [-a] [-d cvsroot] [-f] [-m msgprefix] [PARENTCOMMIT] COMMITID
DESCRIPTION
Add authorship information. Adds Author line, and Committer (if
different from Author) to the message.
+-d::
+ Set an alternative CVSROOT to use. This corresponds to the CVS
+ -d parameter. Usually users will not want to set this, except
+ if using CVS in an asymmetric fashion.
+
-f::
Force the merge even if the files are not up to date.
+++ /dev/null
-git-diff-stages(1)
-==================
-
-NAME
-----
-git-diff-stages - Compares two merge stages in the index
-
-
-SYNOPSIS
---------
-'git-diff-stages' [<common diff options>] <stage1> <stage2> [<path>...]
-
-DESCRIPTION
------------
-DEPRECATED and will be removed in 1.5.1.
-
-Compares the content and mode of the blobs in two stages in an
-unmerged index file.
-
-OPTIONS
--------
-include::diff-options.txt[]
-
-<stage1>,<stage2>::
- The stage number to be compared.
-
-Output format
--------------
-include::diff-format.txt[]
-
-
-Author
-------
-Written by Junio C Hamano <junkio@cox.net>
-
-Documentation
---------------
-Documentation by Junio C Hamano.
-
-GIT
----
-Part of the gitlink:git[7] suite
SYNOPSIS
--------
-'git-name-rev' [--tags] ( --all | --stdin | <committish>... )
+'git-name-rev' [--tags] [--refs=<pattern>]
+ ( --all | --stdin | <committish>... )
DESCRIPTION
-----------
--tags::
Do not use branch names, but only tags to name the commits
+--refs=<pattern>::
+ Only use refs whose names match a given shell pattern.
+
--all::
List all commits reachable from all refs
'git-remote' add <name> <url>
'git-remote' show <name>
'git-remote' prune <name>
+'git-remote' update [group]
DESCRIPTION
-----------
Deletes all stale tracking branches under <name>.
These stale branches have already been removed from the remote repository
-referenced by <name>, but are still locally available in "remotes/<name>".
+referenced by <name>, but are still locally available in
+"remotes/<name>".
+
+'update'::
+
+Fetch updates for a named set of remotes in the repository as defined by
+remotes.<group>. If a named group is not specified on the command line,
+the configuration parameter remotes.default will get used; if
+remotes.default is not defined, all remotes which do not the
+configuration parameter remote.<name>.skipDefaultUpdate set to true will
+be updated. (See gitlink:git-config[1]).
DISCUSSION
+++ /dev/null
-git-resolve(1)
-==============
-
-NAME
-----
-git-resolve - Merge two commits
-
-
-SYNOPSIS
---------
-'git-resolve' <current> <merged> <message>
-
-DESCRIPTION
------------
-DEPRECATED and will be removed in 1.5.1. Use `git-merge` instead.
-
-Given two commits and a merge message, merge the <merged> commit
-into <current> commit, with the commit log message <message>.
-
-When <current> is a descendant of <merged>, or <current> is an
-ancestor of <merged>, no new commit is created and the <message>
-is ignored. The former is informally called "already up to
-date", and the latter is often called "fast forward".
-
-
-Author
-------
-Written by Linus Torvalds <torvalds@osdl.org> and
-Dan Holmsand <holmsand@gmail.com>.
-
-Documentation
---------------
-Documentation by David Greaves, Junio C Hamano and the git-list <git@vger.kernel.org>.
-
-GIT
----
-Part of the gitlink:git[7] suite
-
[ \--pretty | \--header ]
[ \--bisect ]
[ \--merge ]
+ [ \--reverse ]
[ \--walk-reflogs ]
<commit>... [ \-- <paths>... ]
parent comes before all of its children, but otherwise things
are still ordered in the commit timestamp order.
+--reverse::
+
+ Output the commits in reverse order.
+
Object Traversal
~~~~~~~~~~~~~~~~
You are reading the documentation for the latest version of git.
Documentation for older releases are available here:
+* link:v1.5.0.1/git.html[documentation for release 1.5.0.1]
+
+* link:v1.5.0.1/RelNotes-1.5.0.1.txt[release notes for 1.5.0.1]
+
+* link:v1.5.0/git.html[documentation for release 1.5.0]
+
+* link:v1.5.0/RelNotes-1.5.0.txt[release notes for 1.5.0]
+
* link:v1.4.4.4/git.html[documentation for release 1.4.4.4]
* link:v1.3.3/git.html[documentation for release 1.3.3]
------------------------------------------------
$ git checkout master
-$ git resolve master revert-c99 fast ;# this should be a fast forward
+$ git merge revert-c99 ;# this should be a fast forward
Updating from 10d781b9caa4f71495c7b34963bef137216f86a8 to e3a693c...
cache.h | 8 ++++----
commit.c | 2 +-
5 files changed, 8 insertions(+), 8 deletions(-)
------------------------------------------------
-The 'fast' in the above 'git resolve' is not a magic. I knew this
-'resolve' would result in a fast forward merge, and if not, there is
-something very wrong (so I would do 'git reset' on the 'master' branch
-and examine the situation). When a fast forward merge is done, the
-message parameter to 'git resolve' is discarded, because no new commit
-is created. You could have said 'junk' or 'nothing' there as well.
-
There is no need to redo the test at this point. We fast forwarded
and we know 'master' matches 'revert-c99' exactly. In fact:
$ git-merge-index git-merge-one-file hello.c
-------------------------------------------------
-and that is what higher level `git resolve` is implemented with.
+and that is what higher level `git merge -s resolve` is implemented with.
How git stores objects efficiently: pack files
----------------------------------------------
#!/bin/sh
GVF=GIT-VERSION-FILE
-DEF_VER=v1.5.0.1.GIT
+DEF_VER=v1.5.0.GIT
LF='
'
git-merge-one-file.sh git-parse-remote.sh \
git-pull.sh git-rebase.sh \
git-repack.sh git-request-pull.sh git-reset.sh \
- git-resolve.sh git-revert.sh git-sh-setup.sh \
+ git-revert.sh git-sh-setup.sh \
git-tag.sh git-verify-tag.sh \
git-applymbox.sh git-applypatch.sh git-am.sh \
git-merge.sh git-merge-stupid.sh git-merge-octopus.sh \
builtin-diff.o \
builtin-diff-files.o \
builtin-diff-index.o \
- builtin-diff-stages.o \
builtin-diff-tree.o \
builtin-fmt-merge-msg.o \
builtin-for-each-ref.o \
builtin-ls-tree.o \
builtin-mailinfo.o \
builtin-mailsplit.o \
+ builtin-merge-base.o \
builtin-merge-file.o \
builtin-mv.o \
builtin-name-rev.o \
-Documentation/RelNotes-1.5.0.1.txt
\ No newline at end of file
+Documentation/RelNotes-1.5.1.txt
\ No newline at end of file
*status_p = 0;
- if (!strncmp(buffer, "delta ", 6)) {
+ if (!prefixcmp(buffer, "delta ")) {
patch_method = BINARY_DELTA_DEFLATED;
origlen = strtoul(buffer + 6, NULL, 10);
}
- else if (!strncmp(buffer, "literal ", 8)) {
+ else if (!prefixcmp(buffer, "literal ")) {
patch_method = BINARY_LITERAL_DEFLATED;
origlen = strtoul(buffer + 8, NULL, 10);
}
read_stdin = 0;
continue;
}
- if (!strncmp(arg, "--exclude=", 10)) {
+ if (!prefixcmp(arg, "--exclude=")) {
struct excludes *x = xmalloc(sizeof(*x));
x->path = arg + 10;
x->next = excludes;
excludes = x;
continue;
}
- if (!strncmp(arg, "-p", 2)) {
+ if (!prefixcmp(arg, "-p")) {
p_value = atoi(arg + 2);
continue;
}
line_termination = 0;
continue;
}
- if (!strncmp(arg, "-C", 2)) {
+ if (!prefixcmp(arg, "-C")) {
p_context = strtoul(arg + 2, &end, 0);
if (*end != '\0')
die("unrecognized context count '%s'", arg + 2);
continue;
}
- if (!strncmp(arg, "--whitespace=", 13)) {
+ if (!prefixcmp(arg, "--whitespace=")) {
whitespace_option = arg + 13;
parse_whitespace_option(arg + 13);
continue;
for (i = 1; i < argc; i++) {
const char *arg = argv[i];
- if (!strncmp("--exec=", arg, 7)) {
+ if (!prefixcmp(arg, "--exec=")) {
if (exec_at)
die("multiple --exec specified");
exec = arg + 7;
if (buf[len-1] == '\n')
buf[--len] = 0;
if (strcmp(buf, "ACK")) {
- if (len > 5 && !strncmp(buf, "NACK ", 5))
+ if (len > 5 && !prefixcmp(buf, "NACK "))
die("git-archive: NACK %s", buf + 5);
die("git-archive: protocol error");
}
verbose = 1;
continue;
}
- if (!strncmp(arg, "--format=", 9)) {
+ if (!prefixcmp(arg, "--format=")) {
format = arg + 9;
continue;
}
- if (!strncmp(arg, "--prefix=", 9)) {
+ if (!prefixcmp(arg, "--prefix=")) {
base = arg + 9;
continue;
}
if (!strcmp(arg, "--"))
no_more_options = 1;
if (!no_more_options) {
- if (!strncmp(arg, "--remote=", 9)) {
+ if (!prefixcmp(arg, "--remote=")) {
if (remote)
die("Multiple --remote specified");
remote = arg + 9;
int i, seen_dashdash, unk, opt;
long bottom, top, lno;
int output_option = 0;
+ int show_stats = 0;
const char *revs_file = NULL;
const char *final_commit_name = NULL;
char type[10];
blank_boundary = 1;
else if (!strcmp("--root", arg))
show_root = 1;
+ else if (!strcmp(arg, "--show-stats"))
+ show_stats = 1;
else if (!strcmp("-c", arg))
output_option |= OUTPUT_ANNOTATE_COMPAT;
else if (!strcmp("-t", arg))
output_option |= OUTPUT_LONG_OBJECT_NAME;
else if (!strcmp("-S", arg) && ++i < argc)
revs_file = argv[i];
- else if (!strncmp("-M", arg, 2)) {
+ else if (!prefixcmp(arg, "-M")) {
opt |= PICKAXE_BLAME_MOVE;
blame_move_score = parse_score(arg+2);
}
- else if (!strncmp("-C", arg, 2)) {
+ else if (!prefixcmp(arg, "-C")) {
if (opt & PICKAXE_BLAME_COPY)
opt |= PICKAXE_BLAME_COPY_HARDER;
opt |= PICKAXE_BLAME_COPY | PICKAXE_BLAME_MOVE;
blame_copy_score = parse_score(arg+2);
}
- else if (!strncmp("-L", arg, 2)) {
+ else if (!prefixcmp(arg, "-L")) {
if (!arg[2]) {
if (++i >= argc)
usage(blame_usage);
ent = e;
}
- if (DEBUG) {
+ if (show_stats) {
printf("num read blob: %d\n", num_read_blob);
printf("num get patch: %d\n", num_get_patch);
printf("num commits: %d\n", num_commits);
branch_use_color = git_config_colorbool(var, value);
return 0;
}
- if (!strncmp(var, "color.branch.", 13)) {
+ if (!prefixcmp(var, "color.branch.")) {
int slot = parse_branch_color_slot(var, 13);
color_parse(value, var, branch_colors[slot]);
return 0;
*/
if (!force &&
- !in_merge_bases(rev, head_rev)) {
+ !in_merge_bases(rev, &head_rev, 1)) {
error("The branch '%s' is not a strict subset of "
"your current HEAD.\n"
"If you are sure you want to delete it, "
int len;
/* Detect kind */
- if (!strncmp(refname, "refs/heads/", 11)) {
+ if (!prefixcmp(refname, "refs/heads/")) {
kind = REF_LOCAL_BRANCH;
refname += 11;
- } else if (!strncmp(refname, "refs/remotes/", 13)) {
+ } else if (!prefixcmp(refname, "refs/remotes/")) {
kind = REF_REMOTE_BRANCH;
refname += 13;
- } else if (!strncmp(refname, "refs/tags/", 10)) {
+ } else if (!prefixcmp(refname, "refs/tags/")) {
kind = REF_TAG;
refname += 10;
}
reflog = 1;
continue;
}
- if (!strncmp(arg, "--abbrev=", 9)) {
+ if (!prefixcmp(arg, "--abbrev=")) {
abbrev = atoi(arg+9);
continue;
}
detached = 1;
}
else {
- if (strncmp(head, "refs/heads/", 11))
+ if (prefixcmp(head, "refs/heads/"))
die("HEAD not found below refs/heads!");
head += 11;
}
to_tempfile = 1;
continue;
}
- if (!strncmp(arg, "--prefix=", 9)) {
+ if (!prefixcmp(arg, "--prefix=")) {
state.base_dir = arg+9;
state.base_dir_len = strlen(state.base_dir);
continue;
}
- if (!strncmp(arg, "--stage=", 8)) {
+ if (!prefixcmp(arg, "--stage=")) {
if (!strcmp(arg + 8, "all")) {
to_tempfile = 1;
checkout_stage = CHECKOUT_ALL;
* If --tags, then any tags are used.
* Otherwise only annotated tags are used.
*/
- if (!strncmp(path, "refs/tags/", 10)) {
+ if (!prefixcmp(path, "refs/tags/")) {
if (object->type == OBJ_TAG)
prio = 2;
else
all = 1;
else if (!strcmp(arg, "--tags"))
tags = 1;
- else if (!strncmp(arg, "--abbrev=", 9)) {
+ else if (!prefixcmp(arg, "--abbrev=")) {
abbrev = strtoul(arg + 9, NULL, 10);
if (abbrev != 0 && (abbrev < MINIMUM_ABBREV || 40 < abbrev))
abbrev = DEFAULT_ABBREV;
}
- else if (!strncmp(arg, "--candidates=", 13)) {
+ else if (!prefixcmp(arg, "--candidates=")) {
max_candidates = strtoul(arg + 13, NULL, 10);
if (max_candidates < 1)
max_candidates = 1;
+++ /dev/null
-/*
- * Copyright (c) 2005 Junio C Hamano
- */
-
-#include "cache.h"
-#include "diff.h"
-#include "builtin.h"
-
-static struct diff_options diff_options;
-
-static const char diff_stages_usage[] =
-"git-diff-stages [<common diff options>] <stage1> <stage2> [<path>...]"
-COMMON_DIFF_OPTIONS_HELP;
-
-static void diff_stages(int stage1, int stage2, const char **pathspec)
-{
- int i = 0;
- while (i < active_nr) {
- struct cache_entry *ce, *stages[4] = { NULL, };
- struct cache_entry *one, *two;
- const char *name;
- int len, skip;
-
- ce = active_cache[i];
- skip = !ce_path_match(ce, pathspec);
- len = ce_namelen(ce);
- name = ce->name;
- for (;;) {
- int stage = ce_stage(ce);
- stages[stage] = ce;
- if (active_nr <= ++i)
- break;
- ce = active_cache[i];
- if (ce_namelen(ce) != len ||
- memcmp(name, ce->name, len))
- break;
- }
- one = stages[stage1];
- two = stages[stage2];
-
- if (skip || (!one && !two))
- continue;
- if (!one)
- diff_addremove(&diff_options, '+', ntohl(two->ce_mode),
- two->sha1, name, NULL);
- else if (!two)
- diff_addremove(&diff_options, '-', ntohl(one->ce_mode),
- one->sha1, name, NULL);
- else if (hashcmp(one->sha1, two->sha1) ||
- (one->ce_mode != two->ce_mode) ||
- diff_options.find_copies_harder)
- diff_change(&diff_options,
- ntohl(one->ce_mode), ntohl(two->ce_mode),
- one->sha1, two->sha1, name, NULL);
- }
-}
-
-int cmd_diff_stages(int ac, const char **av, const char *prefix)
-{
- int stage1, stage2;
- const char **pathspec = NULL;
-
- git_config(git_default_config); /* no "diff" UI options */
- read_cache();
- diff_setup(&diff_options);
- while (1 < ac && av[1][0] == '-') {
- const char *arg = av[1];
- if (!strcmp(arg, "-r"))
- ; /* as usual */
- else {
- int diff_opt_cnt;
- diff_opt_cnt = diff_opt_parse(&diff_options,
- av+1, ac-1);
- if (diff_opt_cnt < 0)
- usage(diff_stages_usage);
- else if (diff_opt_cnt) {
- av += diff_opt_cnt;
- ac -= diff_opt_cnt;
- continue;
- }
- else
- usage(diff_stages_usage);
- }
- ac--; av++;
- }
-
- if (!diff_options.output_format)
- diff_options.output_format = DIFF_FORMAT_RAW;
-
- if (ac < 3 ||
- sscanf(av[1], "%d", &stage1) != 1 ||
- ! (0 <= stage1 && stage1 <= 3) ||
- sscanf(av[2], "%d", &stage2) != 1 ||
- ! (0 <= stage2 && stage2 <= 3))
- usage(diff_stages_usage);
-
- av += 3; /* The rest from av[0] are for paths restriction. */
- pathspec = get_pathspec(prefix, av);
-
- if (diff_setup_done(&diff_options) < 0)
- usage(diff_stages_usage);
-
- diff_stages(stage1, stage2, pathspec);
- diffcore_std(&diff_options);
- diff_flush(&diff_options);
- return 0;
-}
if (len < 43 || line[40] != '\t')
return 1;
- if (!strncmp(line + 41, "not-for-merge", 13))
+ if (!prefixcmp(line + 41, "not-for-merge"))
return 0;
if (line[41] != '\t')
if (pulling_head) {
origin = xstrdup(src);
src_data->head_status |= 1;
- } else if (!strncmp(line, "branch ", 7)) {
+ } else if (!prefixcmp(line, "branch ")) {
origin = xstrdup(line + 7);
append_to_list(&src_data->branch, origin, NULL);
src_data->head_status |= 2;
- } else if (!strncmp(line, "tag ", 4)) {
+ } else if (!prefixcmp(line, "tag ")) {
origin = line;
append_to_list(&src_data->tag, xstrdup(origin + 4), NULL);
src_data->head_status |= 2;
- } else if (!strncmp(line, "remote branch ", 14)) {
+ } else if (!prefixcmp(line, "remote branch ")) {
origin = xstrdup(line + 14);
append_to_list(&src_data->r_branch, origin, NULL);
src_data->head_status |= 2;
current_branch = resolve_ref("HEAD", head_sha1, 1, NULL);
if (!current_branch)
die("No current branch");
- if (!strncmp(current_branch, "refs/heads/", 11))
+ if (!prefixcmp(current_branch, "refs/heads/"))
current_branch += 11;
while (fgets(line, sizeof(line), in)) {
i++;
break;
}
- if (!strncmp(arg, "--format=", 9)) {
+ if (!prefixcmp(arg, "--format=")) {
if (format)
die("more than one --format?");
format = arg + 9;
quote_style = QUOTE_TCL;
continue;
}
- if (!strncmp(arg, "--count=", 8)) {
+ if (!prefixcmp(arg, "--count=")) {
if (maxcount)
die("more than one --count?");
maxcount = atoi(arg + 8);
die("The number %s did not parse", arg);
continue;
}
- if (!strncmp(arg, "--sort=", 7)) {
+ if (!prefixcmp(arg, "--sort=")) {
struct ref_sort *s = xcalloc(1, sizeof(*s));
int len;
if (!head_points_at || !(flag & REF_ISSYMREF))
return error("HEAD is not a symbolic ref");
- if (strncmp(head_points_at, "refs/heads/", 11))
+ if (prefixcmp(head_points_at, "refs/heads/"))
return error("HEAD points to something strange (%s)",
head_points_at);
if (is_null_sha1(sha1))
opt.word_regexp = 1;
continue;
}
- if (!strncmp("-A", arg, 2) ||
- !strncmp("-B", arg, 2) ||
- !strncmp("-C", arg, 2) ||
+ if (!prefixcmp(arg, "-A") ||
+ !prefixcmp(arg, "-B") ||
+ !prefixcmp(arg, "-C") ||
(arg[0] == '-' && '1' <= arg[1] && arg[1] <= '9')) {
unsigned num;
const char *scan;
for (i = 1; i < argc; i++, argv++) {
const char *arg = argv[1];
- if (!strncmp(arg, "--template=", 11))
+ if (!prefixcmp(arg, "--template="))
template_dir = arg+11;
else if (!strcmp(arg, "--shared"))
shared_repository = PERM_GROUP;
- else if (!strncmp(arg, "--shared=", 9))
+ else if (!prefixcmp(arg, "--shared="))
shared_repository = git_config_perm("arg", arg+9);
else
usage(init_db_usage);
rev->always_show_header = 0;
for (i = 1; i < argc; i++) {
const char *arg = argv[i];
- if (!strncmp(arg, "--encoding=", 11)) {
+ if (!prefixcmp(arg, "--encoding=")) {
arg += 11;
if (strcmp(arg, "none"))
git_log_output_encoding = strdup(arg);
sol += 2;
/* strip [PATCH] or [PATCH blabla] */
- if (!keep_subject && !strncmp(sol, "[PATCH", 6)) {
+ if (!keep_subject && !prefixcmp(sol, "[PATCH")) {
char *eos = strchr(sol + 6, ']');
if (eos) {
while (isspace(*eos))
else if (!strcmp(argv[i], "-n") ||
!strcmp(argv[i], "--numbered"))
numbered = 1;
- else if (!strncmp(argv[i], "--start-number=", 15))
+ else if (!prefixcmp(argv[i], "--start-number="))
start_number = strtol(argv[i] + 15, NULL, 10);
else if (!strcmp(argv[i], "--start-number")) {
i++;
}
else if (!strcmp(argv[i], "--attach"))
rev.mime_boundary = git_version_string;
- else if (!strncmp(argv[i], "--attach=", 9))
+ else if (!prefixcmp(argv[i], "--attach="))
rev.mime_boundary = argv[i] + 9;
else if (!strcmp(argv[i], "--ignore-if-in-upstream"))
ignore_if_in_upstream = 1;
else if (!strcmp(argv[i], "--thread"))
thread = 1;
- else if (!strncmp(argv[i], "--in-reply-to=", 14))
+ else if (!prefixcmp(argv[i], "--in-reply-to="))
in_reply_to = argv[i] + 14;
else if (!strcmp(argv[i], "--in-reply-to")) {
i++;
die("Need a Message-Id for --in-reply-to");
in_reply_to = argv[i];
}
- else if (!strncmp(argv[i], "--suffix=", 9))
+ else if (!prefixcmp(argv[i], "--suffix="))
fmt_patch_suffix = argv[i] + 9;
else
argv[j++] = argv[i];
add_exclude(argv[++i], "", 0, &dir.exclude_list[EXC_CMDL]);
continue;
}
- if (!strncmp(arg, "--exclude=", 10)) {
+ if (!prefixcmp(arg, "--exclude=")) {
exc_given = 1;
add_exclude(arg+10, "", 0, &dir.exclude_list[EXC_CMDL]);
continue;
add_excludes_from_file(&dir, argv[++i]);
continue;
}
- if (!strncmp(arg, "--exclude-from=", 15)) {
+ if (!prefixcmp(arg, "--exclude-from=")) {
exc_given = 1;
add_excludes_from_file(&dir, arg+15);
continue;
}
- if (!strncmp(arg, "--exclude-per-directory=", 24)) {
+ if (!prefixcmp(arg, "--exclude-per-directory=")) {
exc_given = 1;
dir.exclude_per_dir = arg + 24;
continue;
error_unmatch = 1;
continue;
}
- if (!strncmp(arg, "--abbrev=", 9)) {
+ if (!prefixcmp(arg, "--abbrev=")) {
abbrev = strtoul(arg+9, NULL, 10);
if (abbrev && abbrev < MINIMUM_ABBREV)
abbrev = MINIMUM_ABBREV;
chomp_prefix = 0;
break;
}
- if (!strncmp(argv[1]+2, "abbrev=",7)) {
+ if (!prefixcmp(argv[1]+2, "abbrev=")) {
abbrev = strtoul(argv[1]+9, NULL, 10);
if (abbrev && abbrev < MINIMUM_ABBREV)
abbrev = MINIMUM_ABBREV;
metainfo_charset = def_charset;
else if (!strcmp(argv[1], "-n"))
metainfo_charset = NULL;
- else if (!strncmp(argv[1], "--encoding=", 11))
+ else if (!prefixcmp(argv[1], "--encoding="))
metainfo_charset = argv[1] + 11;
else
usage(mailinfo_usage);
--- /dev/null
+#include "cache.h"
+#include "commit.h"
+
+static int show_merge_base(struct commit *rev1, struct commit *rev2, int show_all)
+{
+ struct commit_list *result = get_merge_bases(rev1, rev2, 0);
+
+ if (!result)
+ return 1;
+
+ while (result) {
+ printf("%s\n", sha1_to_hex(result->item->object.sha1));
+ if (!show_all)
+ return 0;
+ result = result->next;
+ }
+
+ return 0;
+}
+
+static const char merge_base_usage[] =
+"git-merge-base [--all] <commit-id> <commit-id>";
+
+int cmd_merge_base(int argc, const char **argv, const char *prefix)
+{
+ struct commit *rev1, *rev2;
+ unsigned char rev1key[20], rev2key[20];
+ int show_all = 0;
+
+ git_config(git_default_config);
+
+ while (1 < argc && argv[1][0] == '-') {
+ const char *arg = argv[1];
+ if (!strcmp(arg, "-a") || !strcmp(arg, "--all"))
+ show_all = 1;
+ else
+ usage(merge_base_usage);
+ argc--; argv++;
+ }
+ if (argc != 3)
+ usage(merge_base_usage);
+ if (get_sha1(argv[1], rev1key))
+ die("Not a valid object name %s", argv[1]);
+ if (get_sha1(argv[2], rev2key))
+ die("Not a valid object name %s", argv[2]);
+ rev1 = lookup_commit_reference(rev1key);
+ rev2 = lookup_commit_reference(rev2key);
+ if (!rev1 || !rev2)
+ return 1;
+ return show_merge_base(rev1, rev2, show_all);
+}
#include "refs.h"
static const char name_rev_usage[] =
- "git-name-rev [--tags] ( --all | --stdin | committish [committish...] )\n";
+ "git-name-rev [--tags | --refs=<pattern>] ( --all | --stdin | committish [committish...] )\n";
typedef struct rev_name {
const char *tip_name;
parents;
parents = parents->next, parent_number++) {
if (parent_number > 1) {
- char *new_name = xmalloc(strlen(tip_name)+8);
+ int len = strlen(tip_name);
+ char *new_name = xmalloc(len + 8);
+ if (len > 2 && !strcmp(tip_name + len - 2, "^0"))
+ len -= 2;
if (generation > 0)
- sprintf(new_name, "%s~%d^%d", tip_name,
+ sprintf(new_name, "%.*s~%d^%d", len, tip_name,
generation, parent_number);
else
- sprintf(new_name, "%s^%d", tip_name, parent_number);
+ sprintf(new_name, "%.*s^%d", len, tip_name,
+ parent_number);
name_rev(parents->item, new_name,
merge_traversals + 1 , 0, 0);
}
}
+struct name_ref_data {
+ int tags_only;
+ const char *ref_filter;
+};
+
static int name_ref(const char *path, const unsigned char *sha1, int flags, void *cb_data)
{
struct object *o = parse_object(sha1);
- int tags_only = *(int*)cb_data;
+ struct name_ref_data *data = cb_data;
int deref = 0;
- if (tags_only && strncmp(path, "refs/tags/", 10))
+ if (data->tags_only && prefixcmp(path, "refs/tags/"))
+ return 0;
+
+ if (data->ref_filter && fnmatch(data->ref_filter, path, 0))
return 0;
while (o && o->type == OBJ_TAG) {
if (o && o->type == OBJ_COMMIT) {
struct commit *commit = (struct commit *)o;
- if (!strncmp(path, "refs/heads/", 11))
+ if (!prefixcmp(path, "refs/heads/"))
path = path + 11;
- else if (!strncmp(path, "refs/", 5))
+ else if (!prefixcmp(path, "refs/"))
path = path + 5;
name_rev(commit, xstrdup(path), 0, 0, deref);
if (!n->generation)
return n->tip_name;
-
- snprintf(buffer, sizeof(buffer), "%s~%d", n->tip_name, n->generation);
-
- return buffer;
+ else {
+ int len = strlen(n->tip_name);
+ if (len > 2 && !strcmp(n->tip_name + len - 2, "^0"))
+ len -= 2;
+ snprintf(buffer, sizeof(buffer), "%.*s~%d", len, n->tip_name,
+ n->generation);
+
+ return buffer;
+ }
}
int cmd_name_rev(int argc, const char **argv, const char *prefix)
{
struct object_array revs = { 0, 0, NULL };
int as_is = 0, all = 0, transform_stdin = 0;
- int tags_only = 0;
+ struct name_ref_data data = { 0, NULL };
git_config(git_default_config);
as_is = 1;
continue;
} else if (!strcmp(*argv, "--tags")) {
- tags_only = 1;
+ data.tags_only = 1;
+ continue;
+ } else if (!prefixcmp(*argv, "--refs=")) {
+ data.ref_filter = *argv + 7;
continue;
} else if (!strcmp(*argv, "--all")) {
if (argc > 1)
add_object_array((struct object *)commit, *argv, &revs);
}
- for_each_ref(name_ref, &tags_only);
+ for_each_ref(name_ref, &data);
if (transform_stdin) {
char buffer[2048];
incremental = 1;
continue;
}
- if (!strncmp("--window=", arg, 9)) {
+ if (!prefixcmp(arg, "--window=")) {
char *end;
window = strtoul(arg+9, &end, 0);
if (!arg[9] || *end)
usage(pack_usage);
continue;
}
- if (!strncmp("--depth=", arg, 8)) {
+ if (!prefixcmp(arg, "--depth=")) {
char *end;
depth = strtoul(arg+8, &end, 0);
if (!arg[8] || *end)
continue;
}
if (!strcmp("--unpacked", arg) ||
- !strncmp("--unpacked=", arg, 11) ||
+ !prefixcmp(arg, "--unpacked=") ||
!strcmp("--reflog", arg) ||
!strcmp("--all", arg)) {
use_internal_rev_list = 1;
/* Do not pack the symbolic refs */
if ((flags & REF_ISSYMREF))
return 0;
- is_tag_ref = !strncmp(path, "refs/tags/", 10);
+ is_tag_ref = !prefixcmp(path, "refs/tags/");
/* ALWAYS pack refs that were already packed or are tags */
if (!cb->all && !is_tag_ref && !(flags & REF_ISPACKED))
/* Ignore the "refs/" at the beginning of the refname */
ref += 5;
- if (!strncmp(ref, "tags/", 5))
+ if (!prefixcmp(ref, "tags/"))
add_refspec(xstrdup(ref));
return 0;
}
int is_refspec;
char *s, *p;
- if (!strncmp("URL:", buffer, 4)) {
+ if (!prefixcmp(buffer, "URL:")) {
is_refspec = 0;
s = buffer + 4;
- } else if (!strncmp("Push:", buffer, 5)) {
+ } else if (!prefixcmp(buffer, "Push:")) {
is_refspec = 1;
s = buffer + 5;
} else
static int get_remote_config(const char* key, const char* value)
{
- if (!strncmp(key, "remote.", 7) &&
+ if (!prefixcmp(key, "remote.") &&
!strncmp(key + 7, config_repo, config_repo_len)) {
if (!strcmp(key + 7 + config_repo_len, ".url")) {
if (config_current_uri < MAX_URI)
const char **dest_refspec = refspec;
const char *dest = uri[i];
const char *sender = "git-send-pack";
- if (!strncmp(dest, "http://", 7) ||
- !strncmp(dest, "https://", 8))
+ if (!prefixcmp(dest, "http://") ||
+ !prefixcmp(dest, "https://"))
sender = "git-http-push";
else if (thin)
argv[dest_argc++] = "--thin";
verbose=1;
continue;
}
- if (!strncmp(arg, "--repo=", 7)) {
+ if (!prefixcmp(arg, "--repo=")) {
repo = arg+7;
continue;
}
thin = 0;
continue;
}
- if (!strncmp(arg, "--receive-pack=", 15)) {
+ if (!prefixcmp(arg, "--receive-pack=")) {
receivepack = arg;
continue;
}
- if (!strncmp(arg, "--exec=", 7)) {
+ if (!prefixcmp(arg, "--exec=")) {
receivepack = arg;
continue;
}
* entries and put the entries from the tree under the
* given subdirectory.
*/
- if (!strncmp(arg, "--prefix=", 9)) {
+ if (!prefixcmp(arg, "--prefix=")) {
if (stage || opts.merge || opts.prefix)
usage(read_tree_usage);
opts.prefix = arg + 9;
continue;
}
- if (!strncmp(arg, "--exclude-per-directory=", 24)) {
+ if (!prefixcmp(arg, "--exclude-per-directory=")) {
struct dir_struct *dir;
if (opts.dir)
old = lookup_commit_reference_gently(osha1, 1);
if (!new && !is_null_sha1(nsha1))
new = lookup_commit_reference_gently(nsha1, 1);
- if ((old && !in_merge_bases(old, cb->ref_commit)) ||
- (new && !in_merge_bases(new, cb->ref_commit)))
+ if ((old && !in_merge_bases(old, &cb->ref_commit, 1)) ||
+ (new && !in_merge_bases(new, &cb->ref_commit, 1)))
goto prune;
}
const char *arg = argv[i];
if (!strcmp(arg, "--dry-run") || !strcmp(arg, "-n"))
cb.dry_run = 1;
- else if (!strncmp(arg, "--expire=", 9))
+ else if (!prefixcmp(arg, "--expire="))
cb.expire_total = approxidate(arg + 9);
- else if (!strncmp(arg, "--expire-unreachable=", 21))
+ else if (!prefixcmp(arg, "--expire-unreachable="))
cb.expire_unreachable = approxidate(arg + 21);
else if (!strcmp(arg, "--stale-fix"))
cb.stalefix = 1;
SHA1_Init(&ctx);
while (fgets(buf, sizeof(buf), f)) {
- if (!strncmp("<<<<<<< ", buf, 8))
+ if (!prefixcmp(buf, "<<<<<<< "))
hunk = 1;
- else if (!strncmp("=======", buf, 7))
+ else if (!prefixcmp(buf, "======="))
hunk = 2;
- else if (!strncmp(">>>>>>> ", buf, 8)) {
+ else if (!prefixcmp(buf, ">>>>>>> ")) {
hunk_no++;
hunk = 0;
if (memcmp(one->ptr, two->ptr, one->nr < two->nr ?
}
continue;
}
- if (!strncmp(arg,"-n",2)) {
+ if (!prefixcmp(arg, "-n")) {
if ((filter & DO_FLAGS) && (filter & DO_REVS))
show(arg);
continue;
continue;
}
if (!strcmp(arg, "--short") ||
- !strncmp(arg, "--short=", 8)) {
+ !prefixcmp(arg, "--short=")) {
filter &= ~(DO_FLAGS|DO_NOREV);
verify = 1;
abbrev = DEFAULT_ABBREV;
: "false");
continue;
}
- if (!strncmp(arg, "--since=", 8)) {
+ if (!prefixcmp(arg, "--since=")) {
show_datestring("--max-age=", arg+8);
continue;
}
- if (!strncmp(arg, "--after=", 8)) {
+ if (!prefixcmp(arg, "--after=")) {
show_datestring("--max-age=", arg+8);
continue;
}
- if (!strncmp(arg, "--before=", 9)) {
+ if (!prefixcmp(arg, "--before=")) {
show_datestring("--min-age=", arg+9);
continue;
}
- if (!strncmp(arg, "--until=", 8)) {
+ if (!prefixcmp(arg, "--until=")) {
show_datestring("--min-age=", arg+8);
continue;
}
else
free(buffer);
- if (!strncmp(oneline, "[PATCH", 6)) {
+ if (!prefixcmp(oneline, "[PATCH")) {
char *eob = strchr(oneline, ']');
if (eob) {
while (fgets(buffer, sizeof(buffer), stdin) != NULL) {
char *bob;
if ((buffer[0] == 'A' || buffer[0] == 'a') &&
- !strncmp(buffer + 1, "uthor: ", 7) &&
+ !prefixcmp(buffer + 1, "uthor: ") &&
(bob = strchr(buffer + 7, '<')) != NULL) {
char buffer2[1024], offset = 0;
else
eol++;
- if (!strncmp(buffer, "author ", 7)) {
+ if (!prefixcmp(buffer, "author ")) {
char *bracket = strchr(buffer, '<');
if (bracket == NULL || bracket > eol)
pretty, sizeof(pretty), 0, NULL, NULL, 0);
else
strcpy(pretty, "(unavailable)");
- if (!strncmp(pretty, "[PATCH] ", 8))
+ if (!prefixcmp(pretty, "[PATCH] "))
cp = pretty + 8;
else
cp = pretty;
{
unsigned char tmp[20];
int ofs = 11;
- if (strncmp(refname, "refs/heads/", ofs))
+ if (prefixcmp(refname, "refs/heads/"))
return 0;
/* If both heads/foo and tags/foo exists, get_sha1 would
* get confused.
{
unsigned char tmp[20];
int ofs = 13;
- if (strncmp(refname, "refs/remotes/", ofs))
+ if (prefixcmp(refname, "refs/remotes/"))
return 0;
/* If both heads/foo and tags/foo exists, get_sha1 would
* get confused.
static int append_tag_ref(const char *refname, const unsigned char *sha1, int flag, void *cb_data)
{
- if (strncmp(refname, "refs/tags/", 10))
+ if (prefixcmp(refname, "refs/tags/"))
return 0;
return append_ref(refname + 5, sha1, 0);
}
return 0;
if (fnmatch(match_ref_pattern, tail, 0))
return 0;
- if (!strncmp("refs/heads/", refname, 11))
+ if (!prefixcmp(refname, "refs/heads/"))
return append_head_ref(refname, sha1, flag, cb_data);
- if (!strncmp("refs/tags/", refname, 10))
+ if (!prefixcmp(refname, "refs/tags/"))
return append_tag_ref(refname, sha1, flag, cb_data);
return append_ref(refname, sha1, 0);
}
if ((!head[0]) ||
(head_sha1 && sha1 && hashcmp(head_sha1, sha1)))
return 0;
- if (!strncmp(head, "refs/heads/", 11))
+ if (!prefixcmp(head, "refs/heads/"))
head += 11;
- if (!strncmp(name, "refs/heads/", 11))
+ if (!prefixcmp(name, "refs/heads/"))
name += 11;
- else if (!strncmp(name, "heads/", 6))
+ else if (!prefixcmp(name, "heads/"))
name += 6;
return !strcmp(head, name);
}
with_current_branch = 1;
else if (!strcmp(arg, "--sha1-name"))
sha1_name = 1;
- else if (!strncmp(arg, "--more=", 7))
+ else if (!prefixcmp(arg, "--more="))
extra = atoi(arg + 7);
else if (!strcmp(arg, "--merge-base"))
merge_base = 1;
else if (!strcmp(arg, "--reflog") || !strcmp(arg, "-g")) {
reflog = DEFAULT_REFLOG;
}
- else if (!strncmp(arg, "--reflog=", 9))
+ else if (!prefixcmp(arg, "--reflog="))
parse_reflog_param(arg + 9, &reflog, &reflog_base);
- else if (!strncmp(arg, "-g=", 3))
+ else if (!prefixcmp(arg, "-g="))
parse_reflog_param(arg + 3, &reflog, &reflog_base);
else
usage(show_branch_usage);
if (tags_only || heads_only) {
int match;
- match = heads_only && !strncmp(refname, "refs/heads/", 11);
- match |= tags_only && !strncmp(refname, "refs/tags/", 10);
+ match = heads_only && !prefixcmp(refname, "refs/heads/");
+ match |= tags_only && !prefixcmp(refname, "refs/tags/");
if (!match)
return 0;
}
hash_only = 1;
continue;
}
- if (!strncmp(arg, "--hash=", 7) ||
- (!strncmp(arg, "--abbrev", 8) &&
+ if (!prefixcmp(arg, "--hash=") ||
+ (!prefixcmp(arg, "--abbrev") &&
(arg[8] == '=' || arg[8] == '\0'))) {
if (arg[2] != 'h' && !arg[8])
/* --abbrev only */
}
if (!strcmp(arg, "--exclude-existing"))
return exclude_existing(NULL);
- if (!strncmp(arg, "--exclude-existing=", 19))
+ if (!prefixcmp(arg, "--exclude-existing="))
return exclude_existing(arg + 19);
usage(show_ref_usage);
}
unsigned char sha1[20];
while (*pattern) {
- if (!strncmp(*pattern, "refs/", 5) &&
+ if (!prefixcmp(*pattern, "refs/") &&
resolve_ref(*pattern, sha1, 1, NULL)) {
if (!quiet)
show_one(*pattern, sha1);
nargv[nargc++] = "git-archive";
nargv[nargc++] = "--format=tar";
- if (2 <= argc && !strncmp("--remote=", argv[1], 9)) {
+ if (2 <= argc && !prefixcmp(argv[1], "--remote=")) {
nargv[nargc++] = argv[1];
argv++;
argc--;
recover = 1;
continue;
}
- if (!strncmp(arg, "--pack_header=", 14)) {
+ if (!prefixcmp(arg, "--pack_header=")) {
struct pack_header *hdr;
char *c;
const char *arg = argv[1];
if (!strcmp(arg, "--missing-ok"))
missing_ok = 1;
- else if (!strncmp(arg, "--prefix=", 9))
+ else if (!prefixcmp(arg, "--prefix="))
prefix = arg + 9;
else
usage(write_tree_usage);
extern int cmd_diff_files(int argc, const char **argv, const char *prefix);
extern int cmd_diff_index(int argc, const char **argv, const char *prefix);
extern int cmd_diff(int argc, const char **argv, const char *prefix);
-extern int cmd_diff_stages(int argc, const char **argv, const char *prefix);
extern int cmd_diff_tree(int argc, const char **argv, const char *prefix);
extern int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix);
extern int cmd_for_each_ref(int argc, const char **argv, const char *prefix);
extern int cmd_ls_tree(int argc, const char **argv, const char *prefix);
extern int cmd_mailinfo(int argc, const char **argv, const char *prefix);
extern int cmd_mailsplit(int argc, const char **argv, const char *prefix);
+extern int cmd_merge_base(int argc, const char **argv, const char *prefix);
extern int cmd_merge_file(int argc, const char **argv, const char *prefix);
extern int cmd_mv(int argc, const char **argv, const char *prefix);
extern int cmd_name_rev(int argc, const char **argv, const char *prefix);
return result;
}
-int in_merge_bases(struct commit *rev1, struct commit *rev2)
+int in_merge_bases(struct commit *commit, struct commit **reference, int num)
{
struct commit_list *bases, *b;
int ret = 0;
- bases = get_merge_bases(rev1, rev2, 1);
+ if (num == 1)
+ bases = get_merge_bases(commit, *reference, 1);
+ else
+ die("not yet");
for (b = bases; b; b = b->next) {
- if (!hashcmp(rev1->object.sha1, b->item->object.sha1)) {
+ if (!hashcmp(commit->object.sha1, b->item->object.sha1)) {
ret = 1;
break;
}
extern struct commit_list *get_shallow_commits(struct object_array *heads,
int depth, int shallow_flag, int not_shallow_flag);
-int in_merge_bases(struct commit *rev1, struct commit *rev2);
+int in_merge_bases(struct commit *, struct commit **, int);
#endif /* COMMIT_H */
[NO_EXPAT=YesPlease])
AC_SUBST(NO_EXPAT)
#
-# Define NEEDS_LIBICONV if linking with libc is not enough (Darwin).
+# Define NEEDS_LIBICONV if linking with libc is not enough (Darwin and
+# some Solaris installations).
# Define NO_ICONV if neither libc nor libiconv support iconv.
-AC_CHECK_LIB([c], [iconv],
- [NEEDS_LIBICONV=],
- AC_CHECK_LIB([iconv], [iconv],
- [NEEDS_LIBICONV=YesPlease],
- [NO_ICONV=YesPlease]))
+AC_DEFUN([ICONVTEST_SRC], [
+#include <iconv.h>
+
+int main(void)
+{
+ iconv_open("", "");
+ return 0;
+}
+])
+AC_MSG_CHECKING([for iconv in -lc])
+AC_LINK_IFELSE(ICONVTEST_SRC,
+ [AC_MSG_RESULT([yes])
+ NEEDS_LIBICONV=],
+ [AC_MSG_RESULT([no])
+ old_LIBS="$LIBS"
+ LIBS="$LIBS -liconv"
+ AC_MSG_CHECKING([for iconv in -liconv])
+ AC_LINK_IFELSE(ICONVTEST_SRC,
+ [AC_MSG_RESULT([yes])
+ NEEDS_LIBICONV=YesPlease],
+ [AC_MSG_RESULT([no])
+ NO_ICONV=YesPlease])
+ LIBS="$old_LIBS"])
AC_SUBST(NEEDS_LIBICONV)
AC_SUBST(NO_ICONV)
test -n "$NEEDS_LIBICONV" && LIBS="$LIBS -liconv"
line[--len] = 0;
if (!strcmp(line, "NAK"))
return 0;
- if (!strncmp(line, "ACK ", 4)) {
+ if (!prefixcmp(line, "ACK ")) {
if (!get_sha1_hex(line+4, result_sha1)) {
if (strstr(line+45, "continue"))
return 2;
*/
if (namelen != patlen &&
patlen != namelen - 5 &&
- strncmp(name, "refs/heads/", 11) &&
- strncmp(name, "refs/tags/", 10)) {
+ prefixcmp(name, "refs/heads/") &&
+ prefixcmp(name, "refs/tags/")) {
/* We want to catch the case where only weak
* matches are found and there are multiple
* matches, and where more than one strong
cvsimport) : import;;
cvsserver) : daemon;;
daemon) : daemon;;
- diff-stages) : nobody uses it;;
fast-import) : import;;
fsck-objects) : plumbing;;
fetch-pack) : plumbing;;
reflog) : plumbing;;
repo-config) : plumbing;;
rerere) : plumbing;;
- resolve) : dead dont use;;
rev-list) : plumbing;;
rev-parse) : plumbing;;
runstatus) : plumbing;;
--- /dev/null
+#!/bin/sh
+#
+# Copyright (c) 2005 Linus Torvalds
+#
+# Resolve two trees.
+#
+
+echo 'WARNING: This command is DEPRECATED and will be removed very soon.' >&2
+echo 'WARNING: Please use git-merge or git-pull instead.' >&2
+sleep 2
+
+USAGE='<head> <remote> <merge-message>'
+. git-sh-setup
+
+dropheads() {
+ rm -f -- "$GIT_DIR/MERGE_HEAD" \
+ "$GIT_DIR/LAST_MERGE" || exit 1
+}
+
+head=$(git-rev-parse --verify "$1"^0) &&
+merge=$(git-rev-parse --verify "$2"^0) &&
+merge_name="$2" &&
+merge_msg="$3" || usage
+
+#
+# The remote name is just used for the message,
+# but we do want it.
+#
+if [ -z "$head" -o -z "$merge" -o -z "$merge_msg" ]; then
+ usage
+fi
+
+dropheads
+echo $head > "$GIT_DIR"/ORIG_HEAD
+echo $merge > "$GIT_DIR"/LAST_MERGE
+
+common=$(git-merge-base $head $merge)
+if [ -z "$common" ]; then
+ die "Unable to find common commit between" $merge $head
+fi
+
+case "$common" in
+"$merge")
+ echo "Already up-to-date. Yeeah!"
+ dropheads
+ exit 0
+ ;;
+"$head")
+ echo "Updating $(git-rev-parse --short $head)..$(git-rev-parse --short $merge)"
+ git-read-tree -u -m $head $merge || exit 1
+ git-update-ref -m "resolve $merge_name: Fast forward" \
+ HEAD "$merge" "$head"
+ git-diff-tree -p $head $merge | git-apply --stat
+ dropheads
+ exit 0
+ ;;
+esac
+
+# We are going to make a new commit.
+git var GIT_COMMITTER_IDENT >/dev/null || exit
+
+# Find an optimum merge base if there are more than one candidates.
+LF='
+'
+common=$(git-merge-base -a $head $merge)
+case "$common" in
+?*"$LF"?*)
+ echo "Trying to find the optimum merge base."
+ G=.tmp-index$$
+ best=
+ best_cnt=-1
+ for c in $common
+ do
+ rm -f $G
+ GIT_INDEX_FILE=$G git-read-tree -m $c $head $merge \
+ 2>/dev/null || continue
+ # Count the paths that are unmerged.
+ cnt=`GIT_INDEX_FILE=$G git-ls-files --unmerged | wc -l`
+ if test $best_cnt -le 0 -o $cnt -le $best_cnt
+ then
+ best=$c
+ best_cnt=$cnt
+ if test "$best_cnt" -eq 0
+ then
+ # Cannot do any better than all trivial merge.
+ break
+ fi
+ fi
+ done
+ rm -f $G
+ common="$best"
+esac
+
+echo "Trying to merge $merge into $head using $common."
+git-update-index --refresh 2>/dev/null
+git-read-tree -u -m $common $head $merge || exit 1
+result_tree=$(git-write-tree 2> /dev/null)
+if [ $? -ne 0 ]; then
+ echo "Simple merge failed, trying Automatic merge"
+ git-merge-index -o git-merge-one-file -a
+ if [ $? -ne 0 ]; then
+ echo $merge > "$GIT_DIR"/MERGE_HEAD
+ die "Automatic merge failed, fix up by hand"
+ fi
+ result_tree=$(git-write-tree) || exit 1
+fi
+result_commit=$(echo "$merge_msg" | git-commit-tree $result_tree -p $head -p $merge)
+echo "Committed merge $result_commit"
+git-update-ref -m "resolve $merge_name: In-index merge" \
+ HEAD "$result_commit" "$head"
+git-diff-tree -p $head $result_commit | git-apply --stat
+dropheads
static int git_daemon_config(const char *var, const char *value)
{
- if (!strncmp(var, "daemon.", 7) &&
+ if (!prefixcmp(var, "daemon.") &&
!strcmp(var + 7, service_looking_at->config_name)) {
service_enabled = git_config_bool(var, value);
return 0;
for (i = 0; i < ARRAY_SIZE(daemon_service); i++) {
struct daemon_service *s = &(daemon_service[i]);
int namelen = strlen(s->name);
- if (!strncmp("git-", line, 4) &&
+ if (!prefixcmp(line, "git-") &&
!strncmp(s->name, line + 4, namelen) &&
line[namelen + 4] == ' ') {
/*
for (i = 1; i < argc; i++) {
char *arg = argv[i];
- if (!strncmp(arg, "--listen=", 9)) {
+ if (!prefixcmp(arg, "--listen=")) {
char *p = arg + 9;
char *ph = listen_addr = xmalloc(strlen(arg + 9) + 1);
while (*p)
*ph = 0;
continue;
}
- if (!strncmp(arg, "--port=", 7)) {
+ if (!prefixcmp(arg, "--port=")) {
char *end;
unsigned long n;
n = strtoul(arg+7, &end, 0);
export_all_trees = 1;
continue;
}
- if (!strncmp(arg, "--timeout=", 10)) {
+ if (!prefixcmp(arg, "--timeout=")) {
timeout = atoi(arg+10);
continue;
}
- if (!strncmp(arg, "--init-timeout=", 15)) {
+ if (!prefixcmp(arg, "--init-timeout=")) {
init_timeout = atoi(arg+15);
continue;
}
strict_paths = 1;
continue;
}
- if (!strncmp(arg, "--base-path=", 12)) {
+ if (!prefixcmp(arg, "--base-path=")) {
base_path = arg+12;
continue;
}
- if (!strncmp(arg, "--interpolated-path=", 20)) {
+ if (!prefixcmp(arg, "--interpolated-path=")) {
interpolated_path = arg+20;
continue;
}
user_path = "";
continue;
}
- if (!strncmp(arg, "--user-path=", 12)) {
+ if (!prefixcmp(arg, "--user-path=")) {
user_path = arg + 12;
continue;
}
- if (!strncmp(arg, "--pid-file=", 11)) {
+ if (!prefixcmp(arg, "--pid-file=")) {
pid_file = arg + 11;
continue;
}
log_syslog = 1;
continue;
}
- if (!strncmp(arg, "--user=", 7)) {
+ if (!prefixcmp(arg, "--user=")) {
user_name = arg + 7;
continue;
}
- if (!strncmp(arg, "--group=", 8)) {
+ if (!prefixcmp(arg, "--group=")) {
group_name = arg + 8;
continue;
}
- if (!strncmp(arg, "--enable=", 9)) {
+ if (!prefixcmp(arg, "--enable=")) {
enable_service(arg + 9, 1);
continue;
}
- if (!strncmp(arg, "--disable=", 10)) {
+ if (!prefixcmp(arg, "--disable=")) {
enable_service(arg + 10, 0);
continue;
}
- if (!strncmp(arg, "--allow-override=", 17)) {
+ if (!prefixcmp(arg, "--allow-override=")) {
make_service_overridable(arg + 17, 1);
continue;
}
- if (!strncmp(arg, "--forbid-override=", 18)) {
+ if (!prefixcmp(arg, "--forbid-override=")) {
make_service_overridable(arg + 18, 0);
continue;
}
diff_detect_rename_default = DIFF_DETECT_RENAME;
return 0;
}
- if (!strncmp(var, "diff.color.", 11) || !strncmp(var, "color.diff.", 11)) {
+ if (!prefixcmp(var, "diff.color.") || !prefixcmp(var, "color.diff.")) {
int slot = parse_diff_color_slot(var, 11);
color_parse(value, var, diff_colors[slot]);
return 0;
}
}
-static void copy_file(int prefix, const char *data, int size)
+static void copy_file(int prefix, const char *data, int size,
+ const char *set, const char *reset)
{
int ch, nl_just_seen = 1;
while (0 < size--) {
ch = *data++;
- if (nl_just_seen)
+ if (nl_just_seen) {
+ fputs(set, stdout);
putchar(prefix);
- putchar(ch);
- if (ch == '\n')
+ }
+ if (ch == '\n') {
nl_just_seen = 1;
- else
+ fputs(reset, stdout);
+ } else
nl_just_seen = 0;
+ putchar(ch);
}
if (!nl_just_seen)
- printf("\n\\ No newline at end of file\n");
+ printf("%s\n\\ No newline at end of file\n", reset);
}
static void emit_rewrite_diff(const char *name_a,
const char *name_b,
struct diff_filespec *one,
- struct diff_filespec *two)
+ struct diff_filespec *two,
+ int color_diff)
{
int lc_a, lc_b;
+ const char *name_a_tab, *name_b_tab;
+ const char *metainfo = diff_get_color(color_diff, DIFF_METAINFO);
+ const char *fraginfo = diff_get_color(color_diff, DIFF_FRAGINFO);
+ const char *old = diff_get_color(color_diff, DIFF_FILE_OLD);
+ const char *new = diff_get_color(color_diff, DIFF_FILE_NEW);
+ const char *reset = diff_get_color(color_diff, DIFF_RESET);
+
+ name_a_tab = strchr(name_a, ' ') ? "\t" : "";
+ name_b_tab = strchr(name_b, ' ') ? "\t" : "";
+
diff_populate_filespec(one, 0);
diff_populate_filespec(two, 0);
lc_a = count_lines(one->data, one->size);
lc_b = count_lines(two->data, two->size);
- printf("--- a/%s\n+++ b/%s\n@@ -", name_a, name_b);
+ printf("%s--- a/%s%s%s\n%s+++ b/%s%s%s\n%s@@ -",
+ metainfo, name_a, name_a_tab, reset,
+ metainfo, name_b, name_b_tab, reset, fraginfo);
print_line_count(lc_a);
printf(" +");
print_line_count(lc_b);
- printf(" @@\n");
+ printf(" @@%s\n", reset);
if (lc_a)
- copy_file('-', one->data, one->size);
+ copy_file('-', one->data, one->size, old, reset);
if (lc_b)
- copy_file('+', two->data, two->size);
+ copy_file('+', two->data, two->size, new, reset);
}
static int fill_mmfile(mmfile_t *mf, struct diff_filespec *one)
puts(reset);
}
-static void emit_add_line(const char *reset, struct emit_callback *ecbdata, const char *line, int len)
+static void emit_line_with_ws(int nparents,
+ const char *set, const char *reset, const char *ws,
+ const char *line, int len)
{
- int col0 = ecbdata->nparents;
+ int col0 = nparents;
int last_tab_in_indent = -1;
int last_space_in_indent = -1;
int i;
int tail = len;
int need_highlight_leading_space = 0;
- const char *ws = diff_get_color(ecbdata->color_diff, DIFF_WHITESPACE);
- const char *set = diff_get_color(ecbdata->color_diff, DIFF_FILE_NEW);
-
- if (!*ws) {
- emit_line(set, reset, line, len);
- return;
- }
-
/* The line is a newly added line. Does it have funny leading
* whitespaces? In indent, SP should never precede a TAB.
*/
emit_line(set, reset, line + i, len - i);
}
+static void emit_add_line(const char *reset, struct emit_callback *ecbdata, const char *line, int len)
+{
+ const char *ws = diff_get_color(ecbdata->color_diff, DIFF_WHITESPACE);
+ const char *set = diff_get_color(ecbdata->color_diff, DIFF_FILE_NEW);
+
+ if (!*ws)
+ emit_line(set, reset, line, len);
+ else
+ emit_line_with_ws(ecbdata->nparents, set, reset, ws,
+ line, len);
+}
+
static void fn_out_consume(void *priv, char *line, unsigned long len)
{
int i;
const char *reset = diff_get_color(ecbdata->color_diff, DIFF_RESET);
if (ecbdata->label_path[0]) {
- printf("%s--- %s%s\n", set, ecbdata->label_path[0], reset);
- printf("%s+++ %s%s\n", set, ecbdata->label_path[1], reset);
+ const char *name_a_tab, *name_b_tab;
+
+ name_a_tab = strchr(ecbdata->label_path[0], ' ') ? "\t" : "";
+ name_b_tab = strchr(ecbdata->label_path[1], ' ') ? "\t" : "";
+
+ printf("%s--- %s%s%s\n",
+ set, ecbdata->label_path[0], reset, name_a_tab);
+ printf("%s+++ %s%s%s\n",
+ set, ecbdata->label_path[1], reset, name_b_tab);
ecbdata->label_path[0] = ecbdata->label_path[1] = NULL;
}
struct checkdiff_t {
struct xdiff_emit_state xm;
const char *filename;
- int lineno;
+ int lineno, color_diff;
};
static void checkdiff_consume(void *priv, char *line, unsigned long len)
{
struct checkdiff_t *data = priv;
+ const char *ws = diff_get_color(data->color_diff, DIFF_WHITESPACE);
+ const char *reset = diff_get_color(data->color_diff, DIFF_RESET);
+ const char *set = diff_get_color(data->color_diff, DIFF_FILE_NEW);
if (line[0] == '+') {
- int i, spaces = 0;
+ int i, spaces = 0, space_before_tab = 0, white_space_at_end = 0;
/* check space before tab */
for (i = 1; i < len && (line[i] == ' ' || line[i] == '\t'); i++)
if (line[i] == ' ')
spaces++;
if (line[i - 1] == '\t' && spaces)
- printf("%s:%d: space before tab:%.*s\n",
- data->filename, data->lineno, (int)len, line);
+ space_before_tab = 1;
/* check white space at line end */
if (line[len - 1] == '\n')
len--;
if (isspace(line[len - 1]))
- printf("%s:%d: white space at end: %.*s\n",
- data->filename, data->lineno, (int)len, line);
+ white_space_at_end = 1;
+
+ if (space_before_tab || white_space_at_end) {
+ printf("%s:%d: %s", data->filename, data->lineno, ws);
+ if (space_before_tab) {
+ printf("space before tab");
+ if (white_space_at_end)
+ putchar(',');
+ }
+ if (white_space_at_end)
+ printf("white space at end");
+ printf(":%s ", reset);
+ emit_line_with_ws(1, set, reset, ws, line, len);
+ }
data->lineno++;
} else if (line[0] == ' ')
if ((one->mode ^ two->mode) & S_IFMT)
goto free_ab_and_return;
if (complete_rewrite) {
- emit_rewrite_diff(name_a, name_b, one, two);
+ emit_rewrite_diff(name_a, name_b, one, two,
+ o->color_diff);
goto free_ab_and_return;
}
}
xecfg.flags = XDL_EMIT_FUNCNAMES;
if (!diffopts)
;
- else if (!strncmp(diffopts, "--unified=", 10))
+ else if (!prefixcmp(diffopts, "--unified="))
xecfg.ctxlen = strtoul(diffopts + 10, NULL, 10);
- else if (!strncmp(diffopts, "-u", 2))
+ else if (!prefixcmp(diffopts, "-u"))
xecfg.ctxlen = strtoul(diffopts + 2, NULL, 10);
ecb.outf = xdiff_outf;
ecb.priv = &ecbdata;
static void builtin_checkdiff(const char *name_a, const char *name_b,
struct diff_filespec *one,
- struct diff_filespec *two)
+ struct diff_filespec *two, struct diff_options *o)
{
mmfile_t mf1, mf2;
struct checkdiff_t data;
data.xm.consume = checkdiff_consume;
data.filename = name_b ? name_b : name_a;
data.lineno = 0;
+ data.color_diff = o->color_diff;
if (fill_mmfile(&mf1, one) < 0 || fill_mmfile(&mf2, two) < 0)
die("unable to read files to diff");
diff_fill_sha1_info(p->one);
diff_fill_sha1_info(p->two);
- builtin_checkdiff(name, other, p->one, p->two);
+ builtin_checkdiff(name, other, p->one, p->two, o);
}
void diff_setup(struct diff_options *options)
else if (!strcmp(arg, "--shortstat")) {
options->output_format |= DIFF_FORMAT_SHORTSTAT;
}
- else if (!strncmp(arg, "--stat", 6)) {
+ else if (!prefixcmp(arg, "--stat")) {
char *end;
int width = options->stat_width;
int name_width = options->stat_name_width;
switch (*arg) {
case '-':
- if (!strncmp(arg, "-width=", 7))
+ if (!prefixcmp(arg, "-width="))
width = strtoul(arg + 7, &end, 10);
- else if (!strncmp(arg, "-name-width=", 12))
+ else if (!prefixcmp(arg, "-name-width="))
name_width = strtoul(arg + 12, &end, 10);
break;
case '=':
}
else if (!strcmp(arg, "-z"))
options->line_termination = 0;
- else if (!strncmp(arg, "-l", 2))
+ else if (!prefixcmp(arg, "-l"))
options->rename_limit = strtoul(arg+2, NULL, 10);
else if (!strcmp(arg, "--full-index"))
options->full_index = 1;
options->output_format |= DIFF_FORMAT_NAME_STATUS;
else if (!strcmp(arg, "-R"))
options->reverse_diff = 1;
- else if (!strncmp(arg, "-S", 2))
+ else if (!prefixcmp(arg, "-S"))
options->pickaxe = arg + 2;
else if (!strcmp(arg, "-s")) {
options->output_format |= DIFF_FORMAT_NO_OUTPUT;
}
- else if (!strncmp(arg, "-O", 2))
+ else if (!prefixcmp(arg, "-O"))
options->orderfile = arg + 2;
- else if (!strncmp(arg, "--diff-filter=", 14))
+ else if (!prefixcmp(arg, "--diff-filter="))
options->filter = arg + 14;
else if (!strcmp(arg, "--pickaxe-all"))
options->pickaxe_opts = DIFF_PICKAXE_ALL;
else if (!strcmp(arg, "--pickaxe-regex"))
options->pickaxe_opts = DIFF_PICKAXE_REGEX;
- else if (!strncmp(arg, "-B", 2)) {
+ else if (!prefixcmp(arg, "-B")) {
if ((options->break_opt =
diff_scoreopt_parse(arg)) == -1)
return -1;
}
- else if (!strncmp(arg, "-M", 2)) {
+ else if (!prefixcmp(arg, "-M")) {
if ((options->rename_score =
diff_scoreopt_parse(arg)) == -1)
return -1;
options->detect_rename = DIFF_DETECT_RENAME;
}
- else if (!strncmp(arg, "-C", 2)) {
+ else if (!prefixcmp(arg, "-C")) {
if ((options->rename_score =
diff_scoreopt_parse(arg)) == -1)
return -1;
options->find_copies_harder = 1;
else if (!strcmp(arg, "--abbrev"))
options->abbrev = DEFAULT_ABBREV;
- else if (!strncmp(arg, "--abbrev=", 9)) {
+ else if (!prefixcmp(arg, "--abbrev=")) {
options->abbrev = strtoul(arg + 9, NULL, 10);
if (options->abbrev < MINIMUM_ABBREV)
options->abbrev = MINIMUM_ABBREV;
options->xdl_opts |= XDF_IGNORE_WHITESPACE;
else if (!strcmp(arg, "-b") || !strcmp(arg, "--ignore-space-change"))
options->xdl_opts |= XDF_IGNORE_WHITESPACE_CHANGE;
+ else if (!strcmp(arg, "--ignore-space-at-eol"))
+ options->xdl_opts |= XDF_IGNORE_WHITESPACE_AT_EOL;
else if (!strcmp(arg, "--color-words"))
options->color_diff = options->color_diff_words = 1;
else if (!strcmp(arg, "--no-renames"))
int new_len;
/* Ignore line numbers when computing the SHA1 of the patch */
- if (!strncmp(line, "@@ -", 4))
+ if (!prefixcmp(line, "@@ -"))
return;
new_len = remove_space(line, len);
len = strlen(git_command);
/* Trivial cleanup */
- while (!strncmp(exec_dir, "./", 2)) {
+ while (!prefixcmp(exec_dir, "./")) {
exec_dir += 2;
while (*exec_dir == '/')
exec_dir++;
return error("Branch %s is missing commits.", b->name);
}
- if (!in_merge_bases(old_cmit, new_cmit)) {
+ if (!in_merge_bases(old_cmit, &new_cmit, 1)) {
unlock_ref(lock);
warn("Not updating %s"
" (new tip %s does not contain %s)",
static void cmd_mark(void)
{
- if (!strncmp("mark :", command_buf.buf, 6)) {
+ if (!prefixcmp(command_buf.buf, "mark :")) {
next_mark = strtoumax(command_buf.buf + 6, NULL, 10);
read_next_command();
}
size_t length;
char *buffer;
- if (strncmp("data ", command_buf.buf, 5))
+ if (prefixcmp(command_buf.buf, "data "))
die("Expected 'data n' command, found: %s", command_buf.buf);
- if (!strncmp("<<", command_buf.buf + 5, 2)) {
+ if (!prefixcmp(command_buf.buf + 5, "<<")) {
char *term = xstrdup(command_buf.buf + 5 + 2);
size_t sz = 8192, term_len = command_buf.len - 5 - 2;
length = 0;
oe = find_mark(strtoumax(p + 1, &x, 10));
hashcpy(sha1, oe->sha1);
p = x;
- } else if (!strncmp("inline", p, 6)) {
+ } else if (!prefixcmp(p, "inline")) {
inline_data = 1;
p += 6;
} else {
const char *from;
struct branch *s;
- if (strncmp("from ", command_buf.buf, 5))
+ if (prefixcmp(command_buf.buf, "from "))
return;
if (b->branch_tree.tree) {
struct branch *s;
*count = 0;
- while (!strncmp("merge ", command_buf.buf, 6)) {
+ while (!prefixcmp(command_buf.buf, "merge ")) {
from = strchr(command_buf.buf, ' ') + 1;
n = xmalloc(sizeof(*n));
s = lookup_branch(from);
read_next_command();
cmd_mark();
- if (!strncmp("author ", command_buf.buf, 7)) {
+ if (!prefixcmp(command_buf.buf, "author ")) {
author = parse_ident(command_buf.buf + 7);
read_next_command();
}
- if (!strncmp("committer ", command_buf.buf, 10)) {
+ if (!prefixcmp(command_buf.buf, "committer ")) {
committer = parse_ident(command_buf.buf + 10);
read_next_command();
}
for (;;) {
if (1 == command_buf.len)
break;
- else if (!strncmp("M ", command_buf.buf, 2))
+ else if (!prefixcmp(command_buf.buf, "M "))
file_change_m(b);
- else if (!strncmp("D ", command_buf.buf, 2))
+ else if (!prefixcmp(command_buf.buf, "D "))
file_change_d(b);
else if (!strcmp("deleteall", command_buf.buf))
file_change_deleteall(b);
read_next_command();
/* from ... */
- if (strncmp("from ", command_buf.buf, 5))
+ if (prefixcmp(command_buf.buf, "from "))
die("Expected from command, got %s", command_buf.buf);
from = strchr(command_buf.buf, ' ') + 1;
s = lookup_branch(from);
read_next_command();
/* tagger ... */
- if (strncmp("tagger ", command_buf.buf, 7))
+ if (prefixcmp(command_buf.buf, "tagger "))
die("Expected tagger command, got %s", command_buf.buf);
tagger = parse_ident(command_buf.buf + 7);
if (*a != '-' || !strcmp(a, "--"))
break;
- else if (!strncmp(a, "--date-format=", 14)) {
+ else if (!prefixcmp(a, "--date-format=")) {
const char *fmt = a + 14;
if (!strcmp(fmt, "raw"))
whenspec = WHENSPEC_RAW;
else
die("unknown --date-format argument %s", fmt);
}
- else if (!strncmp(a, "--max-pack-size=", 16))
+ else if (!prefixcmp(a, "--max-pack-size="))
max_packsize = strtoumax(a + 16, NULL, 0) * 1024 * 1024;
- else if (!strncmp(a, "--depth=", 8))
+ else if (!prefixcmp(a, "--depth="))
max_depth = strtoul(a + 8, NULL, 0);
- else if (!strncmp(a, "--active-branches=", 18))
+ else if (!prefixcmp(a, "--active-branches="))
max_active_branches = strtoul(a + 18, NULL, 0);
- else if (!strncmp(a, "--export-marks=", 15))
+ else if (!prefixcmp(a, "--export-marks="))
mark_file = a + 15;
- else if (!strncmp(a, "--export-pack-edges=", 20)) {
+ else if (!prefixcmp(a, "--export-pack-edges=")) {
if (pack_edges)
fclose(pack_edges);
pack_edges = fopen(a + 20, "a");
break;
else if (!strcmp("blob", command_buf.buf))
cmd_new_blob();
- else if (!strncmp("commit ", command_buf.buf, 7))
+ else if (!prefixcmp(command_buf.buf, "commit "))
cmd_new_commit();
- else if (!strncmp("tag ", command_buf.buf, 4))
+ else if (!prefixcmp(command_buf.buf, "tag "))
cmd_new_tag();
- else if (!strncmp("reset ", command_buf.buf, 6))
+ else if (!prefixcmp(command_buf.buf, "reset "))
cmd_reset_branch();
else if (!strcmp("checkpoint", command_buf.buf))
cmd_checkpoint();
int len;
while ((len = packet_read_line(fd[0], line, sizeof(line)))) {
- if (!strncmp("shallow ", line, 8)) {
+ if (!prefixcmp(line, "shallow ")) {
if (get_sha1_hex(line + 8, sha1))
die("invalid shallow line: %s", line);
register_shallow(sha1);
continue;
}
- if (!strncmp("unshallow ", line, 10)) {
+ if (!prefixcmp(line, "unshallow ")) {
if (get_sha1_hex(line + 10, sha1))
die("invalid unshallow line: %s", line);
if (!lookup_object(sha1))
check_ref_format(ref->name + 5))
; /* trash */
else if (fetch_all &&
- (!depth || strncmp(ref->name, "refs/tags/", 10) )) {
+ (!depth || prefixcmp(ref->name, "refs/tags/") )) {
*newtail = ref;
ref->next = NULL;
newtail = &ref->next;
char *arg = argv[i];
if (*arg == '-') {
- if (!strncmp("--upload-pack=", arg, 14)) {
+ if (!prefixcmp(arg, "--upload-pack=")) {
uploadpack = arg + 14;
continue;
}
- if (!strncmp("--exec=", arg, 7)) {
+ if (!prefixcmp(arg, "--exec=")) {
uploadpack = arg + 7;
continue;
}
verbose = 1;
continue;
}
- if (!strncmp("--depth=", arg, 8)) {
+ if (!prefixcmp(arg, "--depth=")) {
depth = strtol(arg + 8, NULL, 0);
if (stat(git_path("shallow"), &st))
st.st_mtime = 0;
#ifndef GIT_COMPAT_UTIL_H
#define GIT_COMPAT_UTIL_H
+#define _FILE_OFFSET_BITS 64
+
#ifndef FLEX_ARRAY
#if defined(__GNUC__) && (__GNUC__ < 3)
#define FLEX_ARRAY 0
return x;
}
+static inline int prefixcmp(const char *str, const char *prefix)
+{
+ return strncmp(str, prefix, strlen(prefix));
+}
+
#endif
die "GIT_DIR is not defined or is unreadable";
}
-our ($opt_h, $opt_P, $opt_p, $opt_v, $opt_c, $opt_f, $opt_a, $opt_m );
+our ($opt_h, $opt_P, $opt_p, $opt_v, $opt_c, $opt_f, $opt_a, $opt_m, $opt_d);
-getopts('hPpvcfam:');
+getopts('hPpvcfam:d:');
$opt_h && usage();
die "Need at least one commit identifier!" unless @ARGV;
+my @cvs;
+if ($opt_d) {
+ @cvs = ('cvs', '-d', $opt_d);
+} else {
+ @cvs = ('cvs');
+}
+
# setup a tempdir
our ($tmpdir, $tmpdirname) = tempdir('git-cvsapplycommit-XXXXXX',
TMPDIR => 1,
my $p = $1;
next if (grep { $_ eq $p } @dirs);
}
- my @status = grep(m/^File/, safe_pipe_capture('cvs', '-q', 'status' ,$f));
+ my @status = grep(m/^File/, safe_pipe_capture(@cvs, '-q', 'status' ,$f));
if (@status > 1) { warn 'Strange! cvs status returned more than one line?'};
if (-d dirname $f and $status[0] !~ m/Status: Unknown$/
and $status[0] !~ m/^File: no file /) {
foreach my $f (@files) {
next if grep { $_ eq $f } @afiles;
# TODO:we need to handle removed in cvs
- my @status = grep(m/^File/, safe_pipe_capture('cvs', '-q', 'status' ,$f));
+ my @status = grep(m/^File/, safe_pipe_capture(@cvs, '-q', 'status' ,$f));
if (@status > 1) { warn 'Strange! cvs status returned more than one line?'};
unless ($status[0] =~ m/Status: Up-to-date$/) {
$dirty = 1;
print "Patch applied successfully. Adding new files and directories to CVS\n";
my $dirtypatch = 0;
foreach my $d (@dirs) {
- if (system('cvs','add',$d)) {
+ if (system(@cvs,'add',$d)) {
$dirtypatch = 1;
warn "Failed to cvs add directory $d -- you may need to do it manually";
}
foreach my $f (@afiles) {
if (grep { $_ eq $f } @bfiles) {
- system('cvs', 'add','-kb',$f);
+ system(@cvs, 'add','-kb',$f);
} else {
- system('cvs', 'add', $f);
+ system(@cvs, 'add', $f);
}
if ($?) {
$dirtypatch = 1;
}
foreach my $f (@dfiles) {
- system('cvs', 'rm', '-f', $f);
+ system(@cvs, 'rm', '-f', $f);
if ($?) {
$dirtypatch = 1;
warn "Failed to cvs rm -f $f -- you may need to do it manually";
print "Commit to CVS\n";
print "Patch title (first comment line): $title\n";
my @commitfiles = map { unless (m/\s/) { '\''.$_.'\''; } else { $_; }; } (@files);
-my $cmd = "cvs commit -F .msg @commitfiles";
+my $cmd = join(' ', @cvs)." commit -F .msg @commitfiles";
if ($dirtypatch) {
print "NOTE: One or more hunks failed to apply cleanly.\n";
if ($opt_c) {
print "Autocommit\n $cmd\n";
- print safe_pipe_capture('cvs', 'commit', '-F', '.msg', @files);
+ print safe_pipe_capture(@cvs, 'commit', '-F', '.msg', @files);
if ($?) {
die "Exiting: The commit did not succeed";
}
exit;
}
+ # Check that this is allowed, just as we would with a receive-pack
+ my @cmd = ( $ENV{GIT_DIR}.'hooks/update', "refs/heads/$state->{module}",
+ $parenthash, $commithash );
+ if( -x $cmd[0] ) {
+ unless( system( @cmd ) == 0 )
+ {
+ $log->warn("Commit failed (update hook declined to update ref)");
+ print "error 1 Commit failed (update hook declined)\n";
+ close LOCKFILE;
+ unlink($lockfile);
+ chdir "/";
+ exit;
+ }
+ }
+
print LOCKFILE $commithash;
$updater->update();
orig_head=$(git-rev-parse --verify HEAD 2>/dev/null)
fi
+# Allow --notags from remote.$1.tagopt
+case "$tags$no_tags" in
+'')
+ case "$(git-config --get "remote.$1.tagopt")" in
+ --no-tags)
+ no_tags=t ;;
+ esac
+esac
+
# If --tags (and later --heads or --all) is specified, then we are
# not talking about defaults stored in Pull: line of remotes or
# branches file, and just fetch those and refspecs explicitly given.
$git->command(qw(config --get-regexp), '^remote\.');
};
for (@remotes) {
- if (/^remote\.([^.]*)\.(\S*)\s+(.*)$/) {
+ if (/^remote\.(\S+?)\.([^.\s]+)\s+(.*)$/) {
add_remote_config(\%seen, $1, $2, $3);
}
}
}
}
+sub update_remote {
+ my ($name) = @_;
+
+ my $conf = $git->config("remotes." . $name);
+ if (defined($conf)) {
+ @remotes = split(' ', $conf);
+ } elsif ($name eq 'default') {
+ undef @remotes;
+ for (sort keys %$remote) {
+ my $do_fetch = $git->config_boolean("remote." . $_ .
+ ".skipDefaultUpdate");
+ if (!defined($do_fetch) || $do_fetch ne "true") {
+ push @remotes, $_;
+ }
+ }
+ } else {
+ print STDERR "Remote group $name does not exists.\n";
+ exit(1);
+ }
+ for (@remotes) {
+ print "Updating $_\n";
+ $git->command('fetch', "$_");
+ }
+}
+
sub add_usage {
print STDERR "Usage: git remote add [-f] [-t track]* [-m master] <name> <url>\n";
exit(1);
show_remote($ARGV[$i], $ls_remote);
}
}
+elsif ($ARGV[0] eq 'update') {
+ if (@ARGV <= 1) {
+ update_remote("default");
+ exit(1);
+ }
+ for ($i = 1; $i < @ARGV; $i++) {
+ update_remote($ARGV[$i]);
+ }
+}
elsif ($ARGV[0] eq 'prune') {
my $ls_remote = 1;
my $i;
print STDERR " git remote add <name> <url>\n";
print STDERR " git remote show <name>\n";
print STDERR " git remote prune <name>\n";
+ print STDERR " git remote update [group]\n";
exit(1);
}
+++ /dev/null
-#!/bin/sh
-#
-# Copyright (c) 2005 Linus Torvalds
-#
-# Resolve two trees.
-#
-
-echo 'WARNING: This command is DEPRECATED and will be removed very soon.' >&2
-echo 'WARNING: Please use git-merge or git-pull instead.' >&2
-sleep 2
-
-USAGE='<head> <remote> <merge-message>'
-. git-sh-setup
-
-dropheads() {
- rm -f -- "$GIT_DIR/MERGE_HEAD" \
- "$GIT_DIR/LAST_MERGE" || exit 1
-}
-
-head=$(git-rev-parse --verify "$1"^0) &&
-merge=$(git-rev-parse --verify "$2"^0) &&
-merge_name="$2" &&
-merge_msg="$3" || usage
-
-#
-# The remote name is just used for the message,
-# but we do want it.
-#
-if [ -z "$head" -o -z "$merge" -o -z "$merge_msg" ]; then
- usage
-fi
-
-dropheads
-echo $head > "$GIT_DIR"/ORIG_HEAD
-echo $merge > "$GIT_DIR"/LAST_MERGE
-
-common=$(git-merge-base $head $merge)
-if [ -z "$common" ]; then
- die "Unable to find common commit between" $merge $head
-fi
-
-case "$common" in
-"$merge")
- echo "Already up-to-date. Yeeah!"
- dropheads
- exit 0
- ;;
-"$head")
- echo "Updating $(git-rev-parse --short $head)..$(git-rev-parse --short $merge)"
- git-read-tree -u -m $head $merge || exit 1
- git-update-ref -m "resolve $merge_name: Fast forward" \
- HEAD "$merge" "$head"
- git-diff-tree -p $head $merge | git-apply --stat
- dropheads
- exit 0
- ;;
-esac
-
-# We are going to make a new commit.
-git var GIT_COMMITTER_IDENT >/dev/null || exit
-
-# Find an optimum merge base if there are more than one candidates.
-LF='
-'
-common=$(git-merge-base -a $head $merge)
-case "$common" in
-?*"$LF"?*)
- echo "Trying to find the optimum merge base."
- G=.tmp-index$$
- best=
- best_cnt=-1
- for c in $common
- do
- rm -f $G
- GIT_INDEX_FILE=$G git-read-tree -m $c $head $merge \
- 2>/dev/null || continue
- # Count the paths that are unmerged.
- cnt=`GIT_INDEX_FILE=$G git-ls-files --unmerged | wc -l`
- if test $best_cnt -le 0 -o $cnt -le $best_cnt
- then
- best=$c
- best_cnt=$cnt
- if test "$best_cnt" -eq 0
- then
- # Cannot do any better than all trivial merge.
- break
- fi
- fi
- done
- rm -f $G
- common="$best"
-esac
-
-echo "Trying to merge $merge into $head using $common."
-git-update-index --refresh 2>/dev/null
-git-read-tree -u -m $common $head $merge || exit 1
-result_tree=$(git-write-tree 2> /dev/null)
-if [ $? -ne 0 ]; then
- echo "Simple merge failed, trying Automatic merge"
- git-merge-index -o git-merge-one-file -a
- if [ $? -ne 0 ]; then
- echo $merge > "$GIT_DIR"/MERGE_HEAD
- die "Automatic merge failed, fix up by hand"
- fi
- result_tree=$(git-write-tree) || exit 1
-fi
-result_commit=$(echo "$merge_msg" | git-commit-tree $result_tree -p $head -p $merge)
-echo "Committed merge $result_commit"
-git-update-ref -m "resolve $merge_name: In-index merge" \
- HEAD "$result_commit" "$head"
-git-diff-tree -p $head $result_commit | git-apply --stat
-dropheads
/*
* Check remaining flags.
*/
- if (!strncmp(cmd, "--exec-path", 11)) {
+ if (!prefixcmp(cmd, "--exec-path")) {
cmd += 11;
if (*cmd == '=')
git_set_exec_path(cmd + 1);
setenv(GIT_DIR_ENVIRONMENT, (*argv)[1], 1);
(*argv)++;
(*argc)--;
- } else if (!strncmp(cmd, "--git-dir=", 10)) {
+ } else if (!prefixcmp(cmd, "--git-dir=")) {
setenv(GIT_DIR_ENVIRONMENT, cmd + 10, 1);
} else if (!strcmp(cmd, "--bare")) {
static char git_dir[PATH_MAX+1];
static int git_alias_config(const char *var, const char *value)
{
- if (!strncmp(var, "alias.", 6) && !strcmp(var + 6, alias_command)) {
+ if (!prefixcmp(var, "alias.") && !strcmp(var + 6, alias_command)) {
alias_string = xstrdup(value);
}
return 0;
{ "diff", cmd_diff, RUN_SETUP | USE_PAGER },
{ "diff-files", cmd_diff_files, RUN_SETUP },
{ "diff-index", cmd_diff_index, RUN_SETUP },
- { "diff-stages", cmd_diff_stages, RUN_SETUP },
{ "diff-tree", cmd_diff_tree, RUN_SETUP },
{ "fmt-merge-msg", cmd_fmt_merge_msg, RUN_SETUP },
{ "for-each-ref", cmd_for_each_ref, RUN_SETUP },
{ "fsck", cmd_fsck, RUN_SETUP },
{ "fsck-objects", cmd_fsck, RUN_SETUP },
{ "get-tar-commit-id", cmd_get_tar_commit_id },
- { "grep", cmd_grep, RUN_SETUP },
+ { "grep", cmd_grep, RUN_SETUP | USE_PAGER },
{ "help", cmd_help },
{ "init", cmd_init_db },
{ "init-db", cmd_init_db },
{ "ls-tree", cmd_ls_tree, RUN_SETUP },
{ "mailinfo", cmd_mailinfo },
{ "mailsplit", cmd_mailsplit },
+ { "merge-base", cmd_merge_base, RUN_SETUP },
{ "merge-file", cmd_merge_file },
{ "mv", cmd_mv, RUN_SETUP | NOT_BARE },
{ "name-rev", cmd_name_rev, RUN_SETUP },
* So we just directly call the internal command handler, and
* die if that one cannot handle it.
*/
- if (!strncmp(cmd, "git-", 4)) {
+ if (!prefixcmp(cmd, "git-")) {
cmd += 4;
argv[0] = cmd;
handle_internal_command(argc, argv, envp);
argc--;
handle_options(&argv, &argc);
if (argc > 0) {
- if (!strncmp(argv[0], "--", 2))
+ if (!prefixcmp(argv[0], "--"))
argv[0] += 2;
} else {
/* Default command: "help" */
struct stat st;
int entlen;
- if (strncmp(de->d_name, "git-", 4))
+ if (prefixcmp(de->d_name, "git-"))
continue;
strcpy(path+dirlen, de->d_name);
if (stat(path, &st) || /* stat, not lstat */
{
const char *page;
- if (!strncmp(git_cmd, "git", 3))
+ if (!prefixcmp(git_cmd, "git"))
page = git_cmd;
else {
int page_len = strlen(git_cmd) + 4;
case 'P':
i++;
if (i + 52 <= buffer.posn &&
- !strncmp(data + i, " pack-", 6) &&
- !strncmp(data + i + 46, ".pack\n", 6)) {
+ !prefixcmp(data + i, " pack-") &&
+ !prefixcmp(data + i + 46, ".pack\n")) {
get_sha1_hex(data + i + 6, sha1);
setup_index(repo, sha1);
i += 51;
case 'P':
i++;
if (i + 52 < buffer.posn &&
- !strncmp(data + i, " pack-", 6) &&
- !strncmp(data + i + 46, ".pack\n", 6)) {
+ !prefixcmp(data + i, " pack-") &&
+ !prefixcmp(data + i + 46, ".pack\n")) {
get_sha1_hex(data + i + 6, sha1);
setup_index(sha1);
i += 51;
lock->owner = xmalloc(strlen(ctx->cdata) + 1);
strcpy(lock->owner, ctx->cdata);
} else if (!strcmp(ctx->name, DAV_ACTIVELOCK_TIMEOUT)) {
- if (!strncmp(ctx->cdata, "Second-", 7))
+ if (!prefixcmp(ctx->cdata, "Second-"))
lock->timeout =
strtol(ctx->cdata + 7, NULL, 10);
} else if (!strcmp(ctx->name, DAV_ACTIVELOCK_TOKEN)) {
- if (!strncmp(ctx->cdata, "opaquelocktoken:", 16)) {
+ if (!prefixcmp(ctx->cdata, "opaquelocktoken:")) {
lock->token = xmalloc(strlen(ctx->cdata) - 15);
strcpy(lock->token, ctx->cdata + 16);
}
return;
/* If it's a symref, set the refname; otherwise try for a sha1 */
- if (!strncmp((char *)buffer.buffer, "ref: ", 5)) {
+ if (!prefixcmp((char *)buffer.buffer, "ref: ")) {
*symref = xmalloc(buffer.posn - 5);
strlcpy(*symref, (char *)buffer.buffer + 5, buffer.posn - 5);
} else {
char *p = msg->data;
while (1) {
- if (!strncmp( "From ", p, 5 )) {
+ if (!prefixcmp(p, "From ")) {
count++;
p += 5;
}
data = &all_msgs->data[ *ofs ];
msg->len = all_msgs->len - *ofs;
- if (msg->len < 5 || strncmp( data, "From ", 5 ))
+ if (msg->len < 5 || prefixcmp(data, "From "))
return 0;
p = strchr( data, '\n' );
imap_folder = xstrdup( val );
} else if (!strcmp( "host", key )) {
{
- if (!strncmp( "imap:", val, 5 ))
+ if (!prefixcmp(val, "imap:"))
val += 5;
if (!server.port)
server.port = 143;
}
- if (!strncmp( "//", val, 2 ))
+ if (!prefixcmp(val, "//"))
val += 2;
server.host = xstrdup( val );
}
fix_thin_pack = 1;
} else if (!strcmp(arg, "--keep")) {
keep_msg = "";
- } else if (!strncmp(arg, "--keep=", 7)) {
+ } else if (!prefixcmp(arg, "--keep=")) {
keep_msg = arg + 7;
- } else if (!strncmp(arg, "--pack_header=", 14)) {
+ } else if (!prefixcmp(arg, "--pack_header=")) {
struct pack_header *hdr;
char *c;
+++ /dev/null
-#include "cache.h"
-#include "commit.h"
-
-static int show_all;
-
-static int merge_base(struct commit *rev1, struct commit *rev2)
-{
- struct commit_list *result = get_merge_bases(rev1, rev2, 0);
-
- if (!result)
- return 1;
-
- while (result) {
- printf("%s\n", sha1_to_hex(result->item->object.sha1));
- if (!show_all)
- return 0;
- result = result->next;
- }
-
- return 0;
-}
-
-static const char merge_base_usage[] =
-"git-merge-base [--all] <commit-id> <commit-id>";
-
-int main(int argc, char **argv)
-{
- struct commit *rev1, *rev2;
- unsigned char rev1key[20], rev2key[20];
-
- setup_git_directory();
- git_config(git_default_config);
-
- while (1 < argc && argv[1][0] == '-') {
- char *arg = argv[1];
- if (!strcmp(arg, "-a") || !strcmp(arg, "--all"))
- show_all = 1;
- else
- usage(merge_base_usage);
- argc--; argv++;
- }
- if (argc != 3)
- usage(merge_base_usage);
- if (get_sha1(argv[1], rev1key))
- die("Not a valid object name %s", argv[1]);
- if (get_sha1(argv[2], rev2key))
- die("Not a valid object name %s", argv[2]);
- rev1 = lookup_commit_reference(rev1key);
- rev2 = lookup_commit_reference(rev2key);
- if (!rev1 || !rev2)
- return 1;
- return merge_base(rev1, rev2);
-}
char *arg = argv[i];
if (*arg == '-') {
- if (!strncmp("--upload-pack=", arg, 14)) {
+ if (!prefixcmp(arg, "--upload-pack=")) {
uploadpack = arg + 14;
continue;
}
- if (!strncmp("--exec=", arg, 7)) {
+ if (!prefixcmp(arg, "--exec=")) {
uploadpack = arg + 7;
continue;
}
}
+=item config_boolean ( VARIABLE )
+
+Retrieve the boolean configuration C<VARIABLE>.
+
+Must be called on a repository instance.
+
+This currently wraps command('config') so it is not so fast.
+
+=cut
+
+sub config_boolean {
+ my ($self, $var) = @_;
+ $self->repo_path()
+ or throw Error::Simple("not a repository");
+
+ try {
+ return $self->command_oneline('config', '--bool', '--get',
+ $var);
+ } catch Git::Error::Command with {
+ my $E = shift;
+ if ($E->value() == 1) {
+ # Key not found.
+ return undef;
+ } else {
+ throw $E;
+ }
+ };
+}
+
+
=item ident ( TYPE | IDENTSTR )
=item ident_person ( TYPE | IDENTSTR | IDENTARRAY )
struct ref_lock *lock;
cmd->error_string = NULL;
- if (!strncmp(name, "refs/", 5) && check_ref_format(name + 5)) {
+ if (!prefixcmp(name, "refs/") && check_ref_format(name + 5)) {
cmd->error_string = "funny refname";
return error("refusing to create funny ref '%s' locally",
name);
}
if (deny_non_fast_forwards && !is_null_sha1(new_sha1) &&
!is_null_sha1(old_sha1) &&
- !strncmp(name, "refs/heads/", 11)) {
+ !prefixcmp(name, "refs/heads/")) {
struct commit *old_commit, *new_commit;
struct commit_list *bases, *ent;
goto rollback;
}
- if (!strncmp(oldref, "refs/heads/", 11) &&
- !strncmp(newref, "refs/heads/", 11)) {
+ if (!prefixcmp(oldref, "refs/heads/") &&
+ !prefixcmp(newref, "refs/heads/")) {
char oldsection[1024], newsection[1024];
snprintf(oldsection, 1024, "branch.%s", oldref + 11);
log_file = git_path("logs/%s", ref_name);
if (log_all_ref_updates &&
- (!strncmp(ref_name, "refs/heads/", 11) ||
- !strncmp(ref_name, "refs/remotes/", 13) ||
+ (!prefixcmp(ref_name, "refs/heads/") ||
+ !prefixcmp(ref_name, "refs/remotes/") ||
!strcmp(ref_name, "HEAD"))) {
if (safe_create_leading_directories(log_file) < 0)
return error("unable to create directory for %s",
const char *arg = argv[i];
if (*arg == '-') {
int opts;
- if (!strncmp(arg, "--max-count=", 12)) {
+ if (!prefixcmp(arg, "--max-count=")) {
revs->max_count = atoi(arg + 12);
continue;
}
- if (!strncmp(arg, "--skip=", 7)) {
+ if (!prefixcmp(arg, "--skip=")) {
revs->skip_count = atoi(arg + 7);
continue;
}
revs->max_count = atoi(argv[++i]);
continue;
}
- if (!strncmp(arg,"-n",2)) {
+ if (!prefixcmp(arg, "-n")) {
revs->max_count = atoi(arg + 2);
continue;
}
- if (!strncmp(arg, "--max-age=", 10)) {
+ if (!prefixcmp(arg, "--max-age=")) {
revs->max_age = atoi(arg + 10);
continue;
}
- if (!strncmp(arg, "--since=", 8)) {
+ if (!prefixcmp(arg, "--since=")) {
revs->max_age = approxidate(arg + 8);
continue;
}
- if (!strncmp(arg, "--after=", 8)) {
+ if (!prefixcmp(arg, "--after=")) {
revs->max_age = approxidate(arg + 8);
continue;
}
- if (!strncmp(arg, "--min-age=", 10)) {
+ if (!prefixcmp(arg, "--min-age=")) {
revs->min_age = atoi(arg + 10);
continue;
}
- if (!strncmp(arg, "--before=", 9)) {
+ if (!prefixcmp(arg, "--before=")) {
revs->min_age = approxidate(arg + 9);
continue;
}
- if (!strncmp(arg, "--until=", 8)) {
+ if (!prefixcmp(arg, "--until=")) {
revs->min_age = approxidate(arg + 8);
continue;
}
revs->num_ignore_packed = 0;
continue;
}
- if (!strncmp(arg, "--unpacked=", 11)) {
+ if (!prefixcmp(arg, "--unpacked=")) {
revs->unpacked = 1;
add_ignore_packed(revs, arg+11);
continue;
revs->verbose_header = 1;
continue;
}
- if (!strncmp(arg, "--pretty", 8)) {
+ if (!prefixcmp(arg, "--pretty")) {
revs->verbose_header = 1;
revs->commit_format = get_commit_format(arg+8);
continue;
revs->abbrev = DEFAULT_ABBREV;
continue;
}
- if (!strncmp(arg, "--abbrev=", 9)) {
+ if (!prefixcmp(arg, "--abbrev=")) {
revs->abbrev = strtoul(arg + 9, NULL, 10);
if (revs->abbrev < MINIMUM_ABBREV)
revs->abbrev = MINIMUM_ABBREV;
/*
* Grepping the commit log
*/
- if (!strncmp(arg, "--author=", 9)) {
+ if (!prefixcmp(arg, "--author=")) {
add_header_grep(revs, "author", arg+9);
continue;
}
- if (!strncmp(arg, "--committer=", 12)) {
+ if (!prefixcmp(arg, "--committer=")) {
add_header_grep(revs, "committer", arg+12);
continue;
}
- if (!strncmp(arg, "--grep=", 7)) {
+ if (!prefixcmp(arg, "--grep=")) {
add_message_grep(revs, arg+7);
continue;
}
all_match = 1;
continue;
}
- if (!strncmp(arg, "--encoding=", 11)) {
+ if (!prefixcmp(arg, "--encoding=")) {
arg += 11;
if (strcmp(arg, "none"))
git_log_output_encoding = strdup(arg);
git_log_output_encoding = "";
continue;
}
+ if (!strcmp(arg, "--reverse")) {
+ revs->reverse ^= 1;
+ continue;
+ }
opts = diff_opt_parse(&revs->diffopt, argv+i, argc-i);
if (opts > 0) {
{
struct commit *c = NULL;
+ if (revs->reverse) {
+ struct commit_list *list;
+
+ /*
+ * rev_info.reverse is used to note the fact that we
+ * want to output the list of revisions in reverse
+ * order. To accomplish this goal, reverse can have
+ * different values:
+ *
+ * 0 do nothing
+ * 1 reverse the list
+ * 2 internal use: we have already obtained and
+ * reversed the list, now we only need to yield
+ * its items.
+ */
+
+ if (revs->reverse == 1) {
+ revs->reverse = 0;
+ list = NULL;
+ while ((c = get_revision(revs)))
+ commit_list_insert(c, &list);
+ revs->commits = list;
+ revs->reverse = 2;
+ }
+
+ if (!revs->commits)
+ return NULL;
+ c = revs->commits->item;
+ list = revs->commits->next;
+ free(revs->commits);
+ revs->commits = list;
+ return c;
+ }
+
if (0 < revs->skip_count) {
while ((c = get_revision_1(revs)) != NULL) {
if (revs->skip_count-- <= 0)
unpacked:1, /* see also ignore_packed below */
boundary:1,
left_right:1,
- parents:1;
+ parents:1,
+ reverse:2;
/* Diff flags */
unsigned int diff:1,
char *arg = *argv;
if (*arg == '-') {
- if (!strncmp(arg, "--receive-pack=", 15)) {
+ if (!prefixcmp(arg, "--receive-pack=")) {
receivepack = arg + 15;
continue;
}
- if (!strncmp(arg, "--exec=", 7)) {
+ if (!prefixcmp(arg, "--exec=")) {
receivepack = arg + 7;
continue;
}
offset++;
cwd[len++] = '/';
cwd[len] = 0;
- inside_git_dir = !strncmp(cwd + offset, ".git/", 5);
+ inside_git_dir = !prefixcmp(cwd + offset, ".git/");
return cwd + offset;
}
if (!arg || !(arg = sq_dequote(arg)))
die("bad argument");
- if (strncmp(me, "git-", 4))
+ if (prefixcmp(me, "git-"))
die("bad command");
my_argv[0] = me + 4;
echo "Lots of fun" >>example
git commit -m 'Some fun.' -i hello example
-test_expect_failure 'git resolve now fails' 'git resolve HEAD mybranch "Merge work in mybranch"'
+test_expect_failure 'git resolve now fails' '
+ git merge -m "Merge work in mybranch" mybranch
+'
cat > hello << EOF
Hello World
2 files changed, 2 insertions(+), 0 deletions(-)
EOF
-git resolve HEAD master "Merge upstream changes." | \
- sed -e "1s/[0-9a-f]\{40\}/VARIABLE/g" > resolve.output
+git merge -s "Merge upstream changes." master | \
+ sed -e "1s/[0-9a-f]\{40\}/VARIABLE/g" >resolve.output
test_expect_success 'git resolve' 'cmp resolve.expect resolve.output'
cat > show-branch2.expect << EOF
P2='pathname with SP'
P3='pathname
with LF'
+: >"$P1" 2>&1 && test -f "$P1" && rm -f "$P1" || {
+ echo >&2 'Filesystem does not support tabs in names'
+ test_done
+}
test_expect_success setup '
echo P0.0 >"$P0.0" &&
allowunannotated=$(git-repo-config --bool hooks.allowunannotated)
# --- Check types
-newrev_type=$(git-cat-file -t "$newrev")
+newrev_type=$(git-cat-file -t $newrev)
case "$refname","$newrev_type" in
refs/tags/*,commit)
baserev=$(git-merge-base $oldrev $newrev)
# Commit with a parent
- for rev in $(git-rev-list $newrev ^$baserev)
+ for rev in $(git-rev-parse --not --all | git-rev-list --stdin $newrev ^$baserev)
do
revtype=$(git-cat-file -t "$rev")
echo " via $rev ($revtype)"
fi
echo ""
echo $LOGBEGIN
- git-rev-list --pretty $newrev ^$baserev
+ git-rev-parse --not --all |
+ git-rev-list --stdin --pretty $newrev ^$baserev
echo $LOGEND
echo ""
echo "Diffstat:"
continue;
}
len = strip(line, len);
- if (!strncmp(line, "have ", 5)) {
+ if (!prefixcmp(line, "have ")) {
switch (got_sha1(line+5, sha1)) {
case -1: /* they have what we do not */
if (multi_ack && ok_to_give_up())
if (!len)
break;
- if (!strncmp("shallow ", line, 8)) {
+ if (!prefixcmp(line, "shallow ")) {
unsigned char sha1[20];
struct object *object;
use_thin_pack = 0;
add_object_array(object, NULL, &shallows);
continue;
}
- if (!strncmp("deepen ", line, 7)) {
+ if (!prefixcmp(line, "deepen ")) {
char *end;
use_thin_pack = 0;
depth = strtol(line + 7, &end, 0);
die("Invalid deepen: %s", line);
continue;
}
- if (strncmp("want ", line, 5) ||
+ if (prefixcmp(line, "want ") ||
get_sha1_hex(line+5, sha1_buf))
die("git-upload-pack: protocol error, "
"expected to get sha, not '%s'", line);
strict = 1;
continue;
}
- if (!strncmp(arg, "--timeout=", 10)) {
+ if (!prefixcmp(arg, "--timeout=")) {
timeout = atoi(arg+10);
continue;
}
if (s->branch) {
const char *on_what = "On branch ";
const char *branch_name = s->branch;
- if (!strncmp(branch_name, "refs/heads/", 11))
+ if (!prefixcmp(branch_name, "refs/heads/"))
branch_name += 11;
else if (!strcmp(branch_name, "HEAD")) {
branch_name = "";
wt_status_use_color = git_config_colorbool(k, v);
return 0;
}
- if (!strncmp(k, "status.color.", 13) || !strncmp(k, "color.status.", 13)) {
+ if (!prefixcmp(k, "status.color.") || !prefixcmp(k, "color.status.")) {
int slot = parse_status_slot(k, 13);
color_parse(v, k, wt_status_colors[slot]);
}
#define XDF_NEED_MINIMAL (1 << 1)
#define XDF_IGNORE_WHITESPACE (1 << 2)
#define XDF_IGNORE_WHITESPACE_CHANGE (1 << 3)
-#define XDF_WHITESPACE_FLAGS (XDF_IGNORE_WHITESPACE | XDF_IGNORE_WHITESPACE_CHANGE)
+#define XDF_IGNORE_WHITESPACE_AT_EOL (1 << 4)
+#define XDF_WHITESPACE_FLAGS (XDF_IGNORE_WHITESPACE | XDF_IGNORE_WHITESPACE_CHANGE | XDF_IGNORE_WHITESPACE_AT_EOL)
#define XDL_PATCH_NORMAL '-'
#define XDL_PATCH_REVERSE '+'
return 0;
}
return (i1 >= s1 && i2 >= s2);
+ } else if (flags & XDF_IGNORE_WHITESPACE_AT_EOL) {
+ for (i1 = i2 = 0; i1 < s1 && i2 < s2; ) {
+ if (l1[i1] != l2[i2]) {
+ while (i1 < s1 && isspace(l1[i1]))
+ i1++;
+ while (i2 < s2 && isspace(l2[i2]))
+ i2++;
+ if (i1 < s1 || i2 < s2)
+ return 0;
+ return 1;
+ }
+ i1++;
+ i2++;
+ }
+ return i1 >= s1 && i2 >= s2;
} else
return s1 == s2 && !memcmp(l1, l2, s1);
for (; ptr < top && *ptr != '\n'; ptr++) {
if (isspace(*ptr) && (flags & XDF_WHITESPACE_FLAGS)) {
+ const char *ptr2 = ptr;
while (ptr + 1 < top && isspace(ptr[1])
&& ptr[1] != '\n')
ptr++;
ha += (ha << 5);
ha ^= (unsigned long) ' ';
}
+ if (flags & XDF_IGNORE_WHITESPACE_AT_EOL
+ && ptr[1] != '\n') {
+ while (ptr2 != ptr + 1) {
+ ha += (ha << 5);
+ ha ^= (unsigned long) *ptr2;
+ ptr2++;
+ }
+ }
continue;
}
ha += (ha << 5);