[-n] [-l | --files-with-matches] [-L | --files-without-match]
[-c | --count]
[-A <post-context>] [-B <pre-context>] [-C <context>]
- [-f <file>] [-e <pattern>]
+ [-f <file>] [-e] <pattern>
[<tree>...]
[--] [<path>...]
-f <file>::
Read patterns from <file>, one per line.
+-e::
+ The next parameter is the pattern. This option has to be
+ used for patterns starting with - and should be used in
+ scripts passing user input to grep.
+
`<tree>...`::
Search blobs in the trees for specified patterns.
--skip::
Restart the rebasing process by skipping the current patch.
- This does not work with the --merge option.
--merge::
Use merging strategies to rebase. When the recursive (default) merge
#
# Define NO_STRCASESTR if you don't have strcasestr.
#
+# Define NO_STRLCPY if you don't have strlcpy.
+#
# Define NO_SETENV if you don't have setenv in the C library.
#
# Define NO_SYMLINK_HEAD if you never want .git/HEAD to be a symbolic link.
# because maintaining the nesting to match is a pain. If
# we had "elif" things would have been much nicer...
+ifeq ($(uname_S),Linux)
+ NO_STRLCPY = YesPlease
+endif
ifeq ($(uname_S),Darwin)
NEEDS_SSL_WITH_CRYPTO = YesPlease
NEEDS_LIBICONV = YesPlease
+ NO_STRLCPY = YesPlease
## fink
ifeq ($(shell test -d /sw/lib && echo y),y)
ALL_CFLAGS += -I/sw/include
NEEDS_NSL = YesPlease
SHELL_PATH = /bin/bash
NO_STRCASESTR = YesPlease
+ NO_STRLCPY = YesPlease
ifeq ($(uname_R),5.8)
NEEDS_LIBICONV = YesPlease
NO_UNSETENV = YesPlease
NO_D_TYPE_IN_DIRENT = YesPlease
NO_D_INO_IN_DIRENT = YesPlease
NO_STRCASESTR = YesPlease
+ NO_STRLCPY = YesPlease
NO_SYMLINK_HEAD = YesPlease
NEEDS_LIBICONV = YesPlease
# There are conflicting reports about this.
endif
ifeq ($(uname_S),AIX)
NO_STRCASESTR=YesPlease
+ NO_STRLCPY = YesPlease
NEEDS_LIBICONV=YesPlease
endif
ifeq ($(uname_S),IRIX64)
NO_IPV6=YesPlease
NO_SETENV=YesPlease
NO_STRCASESTR=YesPlease
+ NO_STRLCPY = YesPlease
NO_SOCKADDR_STORAGE=YesPlease
SHELL_PATH=/usr/gnu/bin/bash
ALL_CFLAGS += -DPATH_MAX=1024
COMPAT_CFLAGS += -DNO_STRCASESTR
COMPAT_OBJS += compat/strcasestr.o
endif
+ifdef NO_STRLCPY
+ COMPAT_CFLAGS += -DNO_STRLCPY
+ COMPAT_OBJS += compat/strlcpy.o
+endif
ifdef NO_SETENV
COMPAT_CFLAGS += -DNO_SETENV
COMPAT_OBJS += compat/setenv.o
unsigned long deflate_origlen;
int lines_added, lines_deleted;
int score;
+ int inaccurate_eof:1;
struct fragment *fragments;
char *result;
unsigned long resultsize;
return plen;
}
-static int apply_one_fragment(struct buffer_desc *desc, struct fragment *frag)
+static int apply_one_fragment(struct buffer_desc *desc, struct fragment *frag,
+ int inaccurate_eof)
{
int match_beginning, match_end;
char *buf = desc->buffer;
size -= len;
}
-#ifdef NO_ACCURATE_DIFF
- if (oldsize > 0 && old[oldsize - 1] == '\n' &&
+ if (inaccurate_eof && oldsize > 0 && old[oldsize - 1] == '\n' &&
newsize > 0 && new[newsize - 1] == '\n') {
oldsize--;
newsize--;
}
-#endif
oldlines = old;
newlines = new;
return apply_binary(desc, patch);
while (frag) {
- if (apply_one_fragment(desc, frag) < 0)
+ if (apply_one_fragment(desc, frag, patch->inaccurate_eof) < 0)
return error("patch failed: %s:%ld",
name, frag->oldpos);
frag = frag->next;
return 1;
}
-static int apply_patch(int fd, const char *filename)
+static int apply_patch(int fd, const char *filename, int inaccurate_eof)
{
unsigned long offset, size;
char *buffer = read_patch_file(fd, &size);
int nr;
patch = xcalloc(1, sizeof(*patch));
+ patch->inaccurate_eof = inaccurate_eof;
nr = parse_chunk(buffer + offset, size, patch);
if (nr < 0)
break;
{
int i;
int read_stdin = 1;
+ int inaccurate_eof = 0;
+
const char *whitespace_option = NULL;
for (i = 1; i < argc; i++) {
int fd;
if (!strcmp(arg, "-")) {
- apply_patch(0, "<stdin>");
+ apply_patch(0, "<stdin>", inaccurate_eof);
read_stdin = 0;
continue;
}
parse_whitespace_option(arg + 13);
continue;
}
+ if (!strcmp(arg, "--inaccurate-eof")) {
+ inaccurate_eof = 1;
+ continue;
+ }
if (check_index && prefix_length < 0) {
prefix = setup_git_directory();
usage(apply_usage);
read_stdin = 0;
set_default_whitespace_mode(whitespace_option);
- apply_patch(fd, arg);
+ apply_patch(fd, arg, inaccurate_eof);
close(fd);
}
set_default_whitespace_mode(whitespace_option);
if (read_stdin)
- apply_patch(0, "<stdin>");
+ apply_patch(0, "<stdin>", inaccurate_eof);
if (whitespace_error) {
if (squelch_whitespace_errors &&
squelch_whitespace_errors < whitespace_error) {
int len = 0;
if (output_directory) {
- safe_strncpy(filename, output_directory, 1010);
+ strlcpy(filename, output_directory, 1010);
len = strlen(filename);
if (filename[len - 1] != '/')
filename[len++] = '/';
/* XXX: should we provide more meaningful info here? */
sprintf(header.uid, "%07o", 0);
sprintf(header.gid, "%07o", 0);
- safe_strncpy(header.uname, "git", sizeof(header.uname));
- safe_strncpy(header.gname, "git", sizeof(header.gname));
+ strlcpy(header.uname, "git", sizeof(header.uname));
+ strlcpy(header.gname, "git", sizeof(header.gname));
sprintf(header.devmajor, "%07o", 0);
sprintf(header.devminor, "%07o", 0);
extern int prefer_symlink_refs;
extern int log_all_ref_updates;
extern int warn_ambiguous_refs;
-extern int diff_rename_limit_default;
extern int shared_repository;
extern const char *apply_default_whitespace;
int git_config_perm(const char *var, const char *value);
int adjust_shared_perm(const char *path);
int safe_create_leading_directories(char *path);
-size_t safe_strncpy(char *, const char *, size_t);
char *enter_repo(char *path, int strict);
/* Read and unpack a sha1 file into memory, write memory to a sha1 file */
--- /dev/null
+#include <string.h>
+
+size_t gitstrlcpy(char *dest, const char *src, size_t size)
+{
+ size_t ret = strlen(src);
+
+ if (size) {
+ size_t len = (ret >= size) ? size - 1 : ret;
+ memcpy(dest, src, len);
+ dest[len] = '\0';
+ }
+ return ret;
+}
}
if (!strcmp(var, "user.name")) {
- safe_strncpy(git_default_name, value, sizeof(git_default_name));
+ strlcpy(git_default_name, value, sizeof(git_default_name));
return 0;
}
if (!strcmp(var, "user.email")) {
- safe_strncpy(git_default_email, value, sizeof(git_default_email));
+ strlcpy(git_default_email, value, sizeof(git_default_email));
return 0;
}
if (!strcmp(var, "i18n.commitencoding")) {
- safe_strncpy(git_commit_encoding, value, sizeof(git_commit_encoding));
+ strlcpy(git_commit_encoding, value, sizeof(git_commit_encoding));
return 0;
}
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
+#include <signal.h>
static char *server_capabilities = NULL;
static int use_size_cache;
-int diff_rename_limit_default = -1;
-
-int git_diff_config(const char *var, const char *value)
-{
- if (!strcmp(var, "diff.renamelimit")) {
- diff_rename_limit_default = git_config_int(var, value);
- return 0;
- }
-
- return git_default_config(var, value);
-}
+static int diff_rename_limit_default = -1;
+static int diff_use_color_default = 0;
enum color_diff {
DIFF_RESET = 0,
#define COLOR_CYAN "\033[36m"
#define COLOR_WHITE "\033[37m"
-#define COLOR_CYANBG "\033[46m"
-#define COLOR_GRAYBG "\033[47m" // Good for xterm
-
static const char *diff_colors[] = {
[DIFF_RESET] = COLOR_RESET,
[DIFF_PLAIN] = COLOR_NORMAL,
[DIFF_FILE_NEW] = COLOR_GREEN,
};
+static int parse_diff_color_slot(const char *var, int ofs)
+{
+ if (!strcasecmp(var+ofs, "plain"))
+ return DIFF_PLAIN;
+ if (!strcasecmp(var+ofs, "meta"))
+ return DIFF_METAINFO;
+ if (!strcasecmp(var+ofs, "frag"))
+ return DIFF_FRAGINFO;
+ if (!strcasecmp(var+ofs, "old"))
+ return DIFF_FILE_OLD;
+ if (!strcasecmp(var+ofs, "new"))
+ return DIFF_FILE_NEW;
+ die("bad config variable '%s'", var);
+}
+
+static const char *parse_diff_color_value(const char *value, const char *var)
+{
+ if (!strcasecmp(value, "normal"))
+ return COLOR_NORMAL;
+ if (!strcasecmp(value, "bold"))
+ return COLOR_BOLD;
+ if (!strcasecmp(value, "dim"))
+ return COLOR_DIM;
+ if (!strcasecmp(value, "ul"))
+ return COLOR_UL;
+ if (!strcasecmp(value, "blink"))
+ return COLOR_BLINK;
+ if (!strcasecmp(value, "reverse"))
+ return COLOR_REVERSE;
+ if (!strcasecmp(value, "reset"))
+ return COLOR_RESET;
+ if (!strcasecmp(value, "black"))
+ return COLOR_BLACK;
+ if (!strcasecmp(value, "red"))
+ return COLOR_RED;
+ if (!strcasecmp(value, "green"))
+ return COLOR_GREEN;
+ if (!strcasecmp(value, "yellow"))
+ return COLOR_YELLOW;
+ if (!strcasecmp(value, "blue"))
+ return COLOR_BLUE;
+ if (!strcasecmp(value, "magenta"))
+ return COLOR_MAGENTA;
+ if (!strcasecmp(value, "cyan"))
+ return COLOR_CYAN;
+ if (!strcasecmp(value, "white"))
+ return COLOR_WHITE;
+ die("bad config value '%s' for variable '%s'", value, var);
+}
+
+int git_diff_config(const char *var, const char *value)
+{
+ if (!strcmp(var, "diff.renamelimit")) {
+ diff_rename_limit_default = git_config_int(var, value);
+ return 0;
+ }
+ if (!strcmp(var, "diff.color")) {
+ if (!value)
+ diff_use_color_default = 1; /* bool */
+ else if (!strcasecmp(value, "auto"))
+ diff_use_color_default = isatty(1);
+ else if (!strcasecmp(value, "never"))
+ diff_use_color_default = 0;
+ else if (!strcasecmp(value, "always"))
+ diff_use_color_default = 1;
+ else
+ diff_use_color_default = git_config_bool(var, value);
+ return 0;
+ }
+ if (!strncmp(var, "diff.color.", 11)) {
+ int slot = parse_diff_color_slot(var, 11);
+ diff_colors[slot] = parse_diff_color_value(value, var);
+ return 0;
+ }
+ return git_default_config(var, value);
+}
+
static char *quote_one(const char *str)
{
int needlen;
static int fill_mmfile(mmfile_t *mf, struct diff_filespec *one)
{
if (!DIFF_FILE_VALID(one)) {
- mf->ptr = ""; /* does not matter */
+ mf->ptr = (char *)""; /* does not matter */
mf->size = 0;
return 0;
}
}
for (i = 0; i < data->nr; i++) {
- char *prefix = "";
+ const char *prefix = "";
char *name = data->files[i]->name;
int added = data->files[i]->added;
int deleted = data->files[i]->deleted;
const char *lbl[2];
char *a_one, *b_two;
const char *set = get_color(o->color_diff, DIFF_METAINFO);
- const char *reset = get_color(o->color_diff, DIFF_PLAIN);
+ const char *reset = get_color(o->color_diff, DIFF_RESET);
a_one = quote_two("a/", name_a);
b_two = quote_two("b/", name_b);
memset(&ecbdata, 0, sizeof(ecbdata));
ecbdata.label_path = lbl;
ecbdata.color_diff = o->color_diff;
- xpp.flags = XDF_NEED_MINIMAL;
+ xpp.flags = XDF_NEED_MINIMAL | o->xdl_opts;
xecfg.ctxlen = o->context;
xecfg.flags = XDL_EMIT_FUNCNAMES;
if (!diffopts)
struct diff_filespec *one,
struct diff_filespec *two,
struct diffstat_t *diffstat,
+ struct diff_options *o,
int complete_rewrite)
{
mmfile_t mf1, mf2;
xdemitconf_t xecfg;
xdemitcb_t ecb;
- xpp.flags = XDF_NEED_MINIMAL;
+ xpp.flags = XDF_NEED_MINIMAL | o->xdl_opts;
xecfg.ctxlen = 0;
xecfg.flags = 0;
ecb.outf = xdiff_outf;
err_empty:
err = -1;
empty:
- s->data = "";
+ s->data = (char *)"";
s->size = 0;
return err;
}
if (DIFF_PAIR_UNMERGED(p)) {
/* unmerged */
- builtin_diffstat(p->one->path, NULL, NULL, NULL, diffstat, 0);
+ builtin_diffstat(p->one->path, NULL, NULL, NULL, diffstat, o, 0);
return;
}
if (p->status == DIFF_STATUS_MODIFIED && p->score)
complete_rewrite = 1;
- builtin_diffstat(name, other, p->one, p->two, diffstat, complete_rewrite);
+ builtin_diffstat(name, other, p->one, p->two, diffstat, o, complete_rewrite);
}
static void run_checkdiff(struct diff_filepair *p, struct diff_options *o)
options->change = diff_change;
options->add_remove = diff_addremove;
+ options->color_diff = diff_use_color_default;
}
int diff_setup_done(struct diff_options *options)
return 0;
}
-int opt_arg(const char *arg, int arg_short, const char *arg_long, int *val)
+static int opt_arg(const char *arg, int arg_short, const char *arg_long, int *val)
{
char c, *eq;
int len;
}
else if (!strcmp(arg, "--color"))
options->color_diff = 1;
+ else if (!strcmp(arg, "-w") || !strcmp(arg, "--ignore-all-space"))
+ options->xdl_opts |= XDF_IGNORE_WHITESPACE;
+ else if (!strcmp(arg, "-b") || !strcmp(arg, "--ignore-space-change"))
+ options->xdl_opts |= XDF_IGNORE_WHITESPACE_CHANGE;
else
return 0;
return 1;
free((void*)path_two);
}
-static void diff_flush_name(struct diff_filepair *p,
- int inter_name_termination,
- int line_termination)
+static void diff_flush_name(struct diff_filepair *p, int line_termination)
{
char *path = p->two->path;
if (line_termination)
path = quote_one(p->two->path);
- else
- path = p->two->path;
printf("%s%c", path, line_termination);
if (p->two->path != path)
free(path);
options, diff_output_format);
break;
case DIFF_FORMAT_NAME:
- diff_flush_name(p,
- inter_name_termination,
- line_termination);
+ diff_flush_name(p, line_termination);
break;
case DIFF_FORMAT_NO_OUTPUT:
break;
int setup;
int abbrev;
const char *stat_sep;
+ long xdl_opts;
int nr_paths;
const char **paths;
fi
esac
-sed -e '
- /^diff --git a\/.*/{
- s///
- q
- }
- /^#/d
-' "$GIT_DIR"/COMMIT_EDITMSG |
+if test -z "$no_edit"
+then
+ sed -e '
+ /^diff --git a\/.*/{
+ s///
+ q
+ }
+ /^#/d
+ ' "$GIT_DIR"/COMMIT_EDITMSG
+else
+ cat "$GIT_DIR"/COMMIT_EDITMSG
+fi |
git-stripspace >"$GIT_DIR"/COMMIT_MSG
if cnt=`grep -v -i '^Signed-off-by' "$GIT_DIR"/COMMIT_MSG |
extern char *gitstrcasestr(const char *haystack, const char *needle);
#endif
+#ifdef NO_STRLCPY
+#define strlcpy gitstrlcpy
+extern size_t gitstrlcpy(char *, const char *, size_t);
+#endif
+
static inline void *xmalloc(size_t size)
{
void *ret = malloc(size);
use warnings;
use Getopt::Std;
use File::Spec;
-use File::Temp qw(tempfile);
+use File::Temp qw(tempfile tmpnam);
use File::Path qw(mkpath);
use File::Basename qw(basename dirname);
use Time::Local;
$orig_git_index = $ENV{GIT_INDEX_FILE} if exists $ENV{GIT_INDEX_FILE};
my %index; # holds filenames of one index per branch
-{ # init with an index for origin
- my ($fh, $fn) = tempfile('gitXXXXXX', SUFFIX => '.idx',
- DIR => File::Spec->tmpdir());
- close ($fh);
- $index{$opt_o} = $fn;
-}
+$index{$opt_o} = tmpnam();
+
$ENV{GIT_INDEX_FILE} = $index{$opt_o};
+system("git-read-tree", $opt_o);
+die "read-tree failed: $?\n" if $?;
+
unless(-d $git_dir) {
system("git-init-db");
die "Cannot init the GIT db at $git_tree: $?\n" if $?;
# populate index
unless ($index{$last_branch}) {
- my ($fh, $fn) = tempfile('gitXXXXXX', SUFFIX => '.idx',
- DIR => File::Spec->tmpdir());
- close ($fh);
- $index{$last_branch} = $fn;
+ $index{$last_branch} = tmpnam();
}
$ENV{GIT_INDEX_FILE} = $index{$last_branch};
system('git-read-tree', $last_branch);
if(($ancestor || $branch) ne $last_branch) {
print "Switching from $last_branch to $branch\n" if $opt_v;
unless ($index{$branch}) {
- my ($fh, $fn) = tempfile('gitXXXXXX', SUFFIX => '.idx',
- DIR => File::Spec->tmpdir());
- close ($fh);
- $index{$branch} = $fn;
+ $index{$branch} = tmpnam();
$ENV{GIT_INDEX_FILE} = $index{$branch};
system("git-read-tree", $branch);
die "read-tree failed: $?\n" if $?;
- } else {
+ }
+ # just in case
+ $ENV{GIT_INDEX_FILE} = $index{$branch};
+ if ($ancestor) {
+ print "have ancestor $ancestor" if $opt_v;
+ system("git-read-tree", $ancestor);
+ die "read-tree failed: $?\n" if $?;
+ }
+ } else {
+ # just in case
+ unless ($index{$branch}) {
+ $index{$branch} = tmpnam();
$ENV{GIT_INDEX_FILE} = $index{$branch};
- }
+ system("git-read-tree", $branch);
+ die "read-tree failed: $?\n" if $?;
+ }
}
$last_branch = $branch if $branch ne $last_branch;
$state = 9;
if test -n "`git-diff-index HEAD`"
then
+ printf "Committed: %0${prec}d" $msgnum
git-commit -C "`cat $dotest/current`"
else
- echo "Previous merge succeeded automatically"
+ printf "Already applied: %0${prec}d" $msgnum
fi
+ echo ' '`git-rev-list --pretty=oneline -1 HEAD | \
+ sed 's/^[a-f0-9]\+ //'`
prev_head=`git-rev-parse HEAD^0`
-
# save the resulting commit so we can read-tree on it later
- echo "$prev_head" > "$dotest/cmt.$msgnum.result"
echo "$prev_head" > "$dotest/prev_head"
# onto the next patch:
rv=$?
case "$rv" in
0)
- git-commit -C "$cmt" || die "commit failed: $MRESOLVEMSG"
+ return
;;
1)
test -d "$GIT_DIR/rr-cache" && git-rerere
}
finish_rb_merge () {
- set -e
-
- msgnum=1
- echo "Finalizing rebased commits..."
- git-reset --hard "`cat $dotest/onto`"
- end="`cat $dotest/end`"
- while test "$msgnum" -le "$end"
- do
- git-read-tree `cat "$dotest/cmt.$msgnum.result"`
- git-checkout-index -q -f -u -a
- git-commit -C "`cat $dotest/cmt.$msgnum`"
-
- printf "Committed %0${prec}d" $msgnum
- echo ' '`git-rev-list --pretty=oneline -1 HEAD | \
- sed 's/^[a-f0-9]\+ //'`
- msgnum=$(($msgnum + 1))
- done
rm -r "$dotest"
echo "All done."
}
--skip)
if test -d "$dotest"
then
- die "--skip is not supported when using --merge"
+ prev_head="`cat $dotest/prev_head`"
+ end="`cat $dotest/end`"
+ msgnum="`cat $dotest/msgnum`"
+ msgnum=$(($msgnum + 1))
+ onto="`cat $dotest/onto`"
+ while test "$msgnum" -le "$end"
+ do
+ call_merge "$msgnum"
+ continue_merge
+ done
+ finish_rb_merge
+ exit
fi
git am -3 --skip --resolvemsg="$RESOLVEMSG"
exit
if [ -z "$name" ]; then
echo Nothing new to pack.
else
- echo "Pack pack-$name created."
-
+ if test "$quiet" != '-q'; then
+ echo "Pack pack-$name created."
+ fi
mkdir -p "$PACKDIR" || exit
mv .tmp-pack-$name.pack "$PACKDIR/pack-$name.pack" &&
// skip 'objects' at end
if (okay) {
target = xmalloc(serverlen + posn - i - 6);
- safe_strncpy(target, base, serverlen);
- safe_strncpy(target + serverlen, data + i, posn - i - 6);
+ strlcpy(target, base, serverlen);
+ strlcpy(target + serverlen, data + i, posn - i - 6);
if (get_verbosely)
fprintf(stderr,
"Also look at %s\n", target);
if (ctx->cdata)
free(ctx->cdata);
ctx->cdata = xmalloc(len + 1);
- safe_strncpy(ctx->cdata, s, len + 1);
+ strlcpy(ctx->cdata, s, len + 1);
}
static int remote_ls(struct alt_base *repo, const char *path, int flags,
if (ctx->cdata)
free(ctx->cdata);
ctx->cdata = xmalloc(len + 1);
- safe_strncpy(ctx->cdata, s, len + 1);
+ strlcpy(ctx->cdata, s, len + 1);
}
static struct remote_lock *lock_remote(char *path, long timeout)
return;
path += 8;
obj_hex = xmalloc(strlen(path));
- safe_strncpy(obj_hex, path, 3);
+ strlcpy(obj_hex, path, 3);
strcpy(obj_hex + 2, path + 3);
one_remote_object(obj_hex);
free(obj_hex);
/* If it's a symref, set the refname; otherwise try for a sha1 */
if (!strncmp((char *)buffer.buffer, "ref: ", 5)) {
*symref = xmalloc(buffer.posn - 5);
- safe_strncpy(*symref, (char *)buffer.buffer + 5, buffer.posn - 5);
+ strlcpy(*symref, (char *)buffer.buffer + 5, buffer.posn - 5);
} else {
get_sha1_hex(buffer.buffer, sha1);
}
len = strlen(git_default_email);
git_default_email[len++] = '.';
if (he && (domainname = strchr(he->h_name, '.')))
- safe_strncpy(git_default_email + len, domainname + 1, sizeof(git_default_email) - len);
+ strlcpy(git_default_email + len, domainname + 1, sizeof(git_default_email) - len);
else
- safe_strncpy(git_default_email + len, "(none)", sizeof(git_default_email) - len);
+ strlcpy(git_default_email + len, "(none)", sizeof(git_default_email) - len);
}
/* And set the default date */
datestamp(git_default_date, sizeof(git_default_date));
#include <sys/types.h>
#include <sys/wait.h>
+#include <signal.h>
#include "cache.h"
pch += n;
}
- safe_strncpy(pch, template, len);
+ strlcpy(pch, template, len);
return mkstemp(path);
}
-size_t safe_strncpy(char *dest, const char *src, size_t size)
-{
- size_t ret = strlen(src);
-
- if (size) {
- size_t len = (ret >= size) ? size - 1 : ret;
- memcpy(dest, src, len);
- dest[len] = '\0';
- }
- return ret;
-}
-
-
int validate_symref(const char *path)
{
struct stat st;
#ifndef PKTLINE_H
#define PKTLINE_H
+#include "git-compat-util.h"
+
/*
* Silly packetized line writing interface
*/
const char *vptr = value;
int dup_error = 0;
- if (value_ == NULL)
- value_ = "";
-
if (!use_key_regexp && strcmp(key_, key))
return 0;
if (use_key_regexp && regexec(key_regexp, key_, 0, NULL, 0))
return 0;
if (regexp != NULL &&
(do_not_match ^
- regexec(regexp, value_, 0, NULL, 0)))
+ regexec(regexp, (value_?value_:""), 0, NULL, 0)))
return 0;
if (show_keys)
if (seen && !do_all)
dup_error = 1;
if (type == T_INT)
- sprintf(value, "%d", git_config_int(key_, value_));
+ sprintf(value, "%d", git_config_int(key_, value_?value_:""));
else if (type == T_BOOL)
vptr = git_config_bool(key_, value_) ? "true" : "false";
else
- vptr = value_;
+ vptr = value_?value_:"";
seen++;
if (dup_error) {
error("More than one value for the key %s: %s",
if (str[am] == '@' && str[am+1] == '{' && str[len-1] == '}') {
int date_len = len - am - 3;
char *date_spec = xmalloc(date_len + 1);
- safe_strncpy(date_spec, str + am + 2, date_len + 1);
+ strlcpy(date_spec, str + am + 2, date_len + 1);
at_time = approxidate(date_spec);
free(date_spec);
len = am;
test_expect_success \
'pick top patch from topic branch into master' \
'git-cherry-pick my-topic-branch^0 &&
- git-checkout -f my-topic-branch
+ git-checkout -f my-topic-branch &&
+ git-branch master-merge master &&
+ git-branch my-topic-branch-merge my-topic-branch
'
test_debug \
'rebase topic branch against new master and check git-am did not get halted' \
'git-rebase master && test ! -d .dotest'
+if test -z "$no_python"
+then
+ test_expect_success \
+ 'rebase --merge topic branch that was partially merged upstream' \
+ 'git-checkout -f my-topic-branch-merge &&
+ git-rebase --merge master-merge &&
+ test ! -d .git/.dotest-merge'
+fi
+
test_done
--- /dev/null
+#!/bin/sh
+#
+# Copyright (c) 2006 Eric Wong
+#
+
+test_description='git rebase --merge --skip tests'
+
+. ./test-lib.sh
+
+# we assume the default git-am -3 --skip strategy is tested independently
+# and always works :)
+
+if test "$no_python"; then
+ echo "Skipping: no python => no recursive merge"
+ test_done
+ exit 0
+fi
+
+test_expect_success setup '
+ echo hello > hello &&
+ git add hello &&
+ git commit -m "hello" &&
+ git branch skip-reference &&
+
+ echo world >> hello &&
+ git commit -a -m "hello world" &&
+ echo goodbye >> hello &&
+ git commit -a -m "goodbye" &&
+
+ git checkout -f skip-reference &&
+ echo moo > hello &&
+ git commit -a -m "we should skip this" &&
+ echo moo > cow &&
+ git add cow &&
+ git commit -m "this should not be skipped" &&
+ git branch pre-rebase skip-reference &&
+ git branch skip-merge skip-reference
+ '
+
+test_expect_failure 'rebase with git am -3 (default)' 'git rebase master'
+
+test_expect_success 'rebase --skip with am -3' '
+ git reset --hard HEAD &&
+ git rebase --skip
+ '
+test_expect_success 'checkout skip-merge' 'git checkout -f skip-merge'
+
+test_expect_failure 'rebase with --merge' 'git rebase --merge master'
+
+test_expect_success 'rebase --skip with --merge' '
+ git reset --hard HEAD &&
+ git rebase --skip
+ '
+
+test_expect_success 'merge and reference trees equal' \
+ 'test -z "`git-diff-tree skip-merge skip-reference`"'
+
+test_debug 'gitk --all & sleep 1'
+
+test_done
+
#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 XDL_PATCH_NORMAL '-'
#define XDL_PATCH_REVERSE '+'
long *kvdf, long *kvdb, int need_min, xdpsplit_t *spl,
xdalgoenv_t *xenv);
static xdchange_t *xdl_add_change(xdchange_t *xscr, long i1, long i2, long chg1, long chg2);
-static int xdl_change_compact(xdfile_t *xdf, xdfile_t *xdfo);
+static int xdl_change_compact(xdfile_t *xdf, xdfile_t *xdfo, long flags);
}
-static int xdl_change_compact(xdfile_t *xdf, xdfile_t *xdfo) {
+static int xdl_change_compact(xdfile_t *xdf, xdfile_t *xdfo, long flags) {
long ix, ixo, ixs, ixref, grpsiz, nrec = xdf->nrec;
char *rchg = xdf->rchg, *rchgo = xdfo->rchg;
xrecord_t **recs = xdf->recs;
* the group.
*/
while (ixs > 0 && recs[ixs - 1]->ha == recs[ix - 1]->ha &&
- XDL_RECMATCH(recs[ixs - 1], recs[ix - 1])) {
+ xdl_recmatch(recs[ixs - 1]->ptr, recs[ixs - 1]->size, recs[ix - 1]->ptr, recs[ix - 1]->size, flags)) {
rchg[--ixs] = 1;
rchg[--ix] = 0;
* the group.
*/
while (ix < nrec && recs[ixs]->ha == recs[ix]->ha &&
- XDL_RECMATCH(recs[ixs], recs[ix])) {
+ xdl_recmatch(recs[ixs]->ptr, recs[ixs]->size, recs[ix]->ptr, recs[ix]->size, flags)) {
rchg[ixs++] = 0;
rchg[ix++] = 1;
return -1;
}
- if (xdl_change_compact(&xe.xdf1, &xe.xdf2) < 0 ||
- xdl_change_compact(&xe.xdf2, &xe.xdf1) < 0 ||
+ if (xdl_change_compact(&xe.xdf1, &xe.xdf2, xpp->flags) < 0 ||
+ xdl_change_compact(&xe.xdf2, &xe.xdf1, xpp->flags) < 0 ||
xdl_build_script(&xe, &xscr) < 0) {
xdl_free_env(&xe);
int xdl_emit_diff(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb,
xdemitconf_t const *xecfg);
-
#endif /* #if !defined(XDIFFI_H) */
#define XDL_ISDIGIT(c) ((c) >= '0' && (c) <= '9')
#define XDL_HASHLONG(v, b) (((unsigned long)(v) * GR_PRIME) >> ((CHAR_BIT * sizeof(unsigned long)) - (b)))
#define XDL_PTRFREE(p) do { if (p) { xdl_free(p); (p) = NULL; } } while (0)
-#define XDL_RECMATCH(r1, r2) ((r1)->size == (r2)->size && memcmp((r1)->ptr, (r2)->ptr, (r1)->size) == 0)
#define XDL_LE32_PUT(p, v) \
do { \
unsigned char *__p = (unsigned char *) (p); \
xdlclass_t **rchash;
chastore_t ncha;
long count;
+ long flags;
} xdlclassifier_t;
-static int xdl_init_classifier(xdlclassifier_t *cf, long size);
+static int xdl_init_classifier(xdlclassifier_t *cf, long size, long flags);
static void xdl_free_classifier(xdlclassifier_t *cf);
static int xdl_classify_record(xdlclassifier_t *cf, xrecord_t **rhash, unsigned int hbits,
xrecord_t *rec);
-static int xdl_init_classifier(xdlclassifier_t *cf, long size) {
+static int xdl_init_classifier(xdlclassifier_t *cf, long size, long flags) {
long i;
+ cf->flags = flags;
+
cf->hbits = xdl_hashbits((unsigned int) size);
cf->hsize = 1 << cf->hbits;
line = rec->ptr;
hi = (long) XDL_HASHLONG(rec->ha, cf->hbits);
for (rcrec = cf->rchash[hi]; rcrec; rcrec = rcrec->next)
- if (rcrec->ha == rec->ha && rcrec->size == rec->size &&
- !memcmp(line, rcrec->line, rec->size))
+ if (rcrec->ha == rec->ha &&
+ xdl_recmatch(rcrec->line, rcrec->size,
+ rec->ptr, rec->size, cf->flags))
break;
if (!rcrec) {
top = blk + bsize;
}
prev = cur;
- hav = xdl_hash_record(&cur, top);
+ hav = xdl_hash_record(&cur, top, xpp->flags);
if (nrec >= narec) {
narec *= 2;
if (!(rrecs = (xrecord_t **) xdl_realloc(recs, narec * sizeof(xrecord_t *)))) {
enl1 = xdl_guess_lines(mf1) + 1;
enl2 = xdl_guess_lines(mf2) + 1;
- if (xdl_init_classifier(&cf, enl1 + enl2 + 1) < 0) {
+ if (xdl_init_classifier(&cf, enl1 + enl2 + 1, xpp->flags) < 0) {
return -1;
}
return nl + 1;
}
+int xdl_recmatch(const char *l1, long s1, const char *l2, long s2, long flags)
+{
+ int i1, i2;
+
+ if (flags & XDF_IGNORE_WHITESPACE) {
+ for (i1 = i2 = 0; i1 < s1 && i2 < s2; i1++, i2++) {
+ if (isspace(l1[i1]))
+ while (isspace(l1[i1]) && i1 < s1)
+ i1++;
+ else if (isspace(l2[i2]))
+ while (isspace(l2[i2]) && i2 < s2)
+ i2++;
+ else if (l1[i1] != l2[i2])
+ return l2[i2] - l1[i1];
+ }
+ if (i1 >= s1)
+ return 1;
+ else if (i2 >= s2)
+ return -1;
+ } else if (flags & XDF_IGNORE_WHITESPACE_CHANGE) {
+ for (i1 = i2 = 0; i1 < s1 && i2 < s2; i1++, i2++) {
+ if (isspace(l1[i1])) {
+ if (!isspace(l2[i2]))
+ return -1;
+ while (isspace(l1[i1]) && i1 < s1)
+ i1++;
+ while (isspace(l2[i2]) && i2 < s2)
+ i2++;
+ } else if (l1[i1] != l2[i2])
+ return l2[i2] - l1[i1];
+ }
+ if (i1 >= s1)
+ return 1;
+ else if (i2 >= s2)
+ return -1;
+ } else
+ return s1 == s2 && !memcmp(l1, l2, s1);
+
+ return 0;
+}
-unsigned long xdl_hash_record(char const **data, char const *top) {
+unsigned long xdl_hash_record(char const **data, char const *top, long flags) {
unsigned long ha = 5381;
char const *ptr = *data;
for (; ptr < top && *ptr != '\n'; ptr++) {
+ if (isspace(*ptr) && (flags & XDF_WHITESPACE_FLAGS)) {
+ while (ptr < top && isspace(*ptr) && ptr[1] != '\n')
+ ptr++;
+ if (flags & XDF_IGNORE_WHITESPACE_CHANGE) {
+ ha += (ha << 5);
+ ha ^= (unsigned long) ' ';
+ }
+ continue;
+ }
ha += (ha << 5);
ha ^= (unsigned long) *ptr;
}
void *xdl_cha_first(chastore_t *cha);
void *xdl_cha_next(chastore_t *cha);
long xdl_guess_lines(mmfile_t *mf);
-unsigned long xdl_hash_record(char const **data, char const *top);
+int xdl_recmatch(const char *l1, long s1, const char *l2, long s2, long flags);
+unsigned long xdl_hash_record(char const **data, char const *top, long flags);
unsigned int xdl_hashbits(unsigned int size);
int xdl_num_out(char *out, long val);
long xdl_atol(char const *str, char const **next);