mirror of
https://github.com/git/git.git
synced 2026-04-02 13:00:08 +02:00
Merge commit 'v1.6.3.2' into devel
Conflicts: Makefile decorate.c object.c Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
This commit is contained in:
61
Documentation/RelNotes-1.6.3.2.txt
Normal file
61
Documentation/RelNotes-1.6.3.2.txt
Normal file
@@ -0,0 +1,61 @@
|
||||
GIT v1.6.3.2 Release Notes
|
||||
==========================
|
||||
|
||||
Fixes since v1.6.3.1
|
||||
--------------------
|
||||
|
||||
* A few codepaths picked up the first few bytes from an sha1[] by
|
||||
casting the (char *) pointer to (int *); GCC 4.4 did not like this,
|
||||
and aborted compilation.
|
||||
|
||||
* Some unlink(2) failures went undiagnosed.
|
||||
|
||||
* The "recursive" merge strategy misbehaved when faced rename/delete
|
||||
conflicts while coming up with an intermediate merge base.
|
||||
|
||||
* The low-level merge algorithm did not handle a degenerate case of
|
||||
merging a file with itself using itself as the common ancestor
|
||||
gracefully. It should produce the file itself, but instead
|
||||
produced an empty result.
|
||||
|
||||
* GIT_TRACE mechanism segfaulted when tracing a shell-quoted aliases.
|
||||
|
||||
* OpenBSD also uses st_ctimspec in "struct stat", instead of "st_ctim".
|
||||
|
||||
* With NO_CROSS_DIRECTORY_HARDLINKS, "make install" can be told not to
|
||||
create hardlinks between $(gitexecdir)/git-$builtin_commands and
|
||||
$(bindir)/git.
|
||||
|
||||
* command completion code in bash did not reliably detect that we are
|
||||
in a bare repository.
|
||||
|
||||
* "git add ." in an empty directory complained that pathspec "." did not
|
||||
match anything, which may be technically correct, but not useful. We
|
||||
silently make it a no-op now.
|
||||
|
||||
* "git add -p" (and "patch" action in "git add -i") was broken when
|
||||
the first hunk that adds a line at the top was split into two and
|
||||
both halves are marked to be used.
|
||||
|
||||
* "git blame path" misbehaved at the commit where path became file
|
||||
from a directory with some files in it.
|
||||
|
||||
* "git for-each-ref" had a segfaulting bug when dealing with a tag object
|
||||
created by an ancient git.
|
||||
|
||||
* "git format-patch -k" still added patch numbers if format.numbered
|
||||
configuration was set.
|
||||
|
||||
* "git grep --color ''" did not terminate. The command also had
|
||||
subtle bugs with its -w option.
|
||||
|
||||
* http-push had a small use-after-free bug.
|
||||
|
||||
* "git push" was converting OFS_DELTA pack representation into less
|
||||
efficient REF_DELTA representation unconditionally upon transfer,
|
||||
making the transferred data unnecessarily larger.
|
||||
|
||||
* "git remote show origin" segfaulted when origin was still empty.
|
||||
|
||||
Many other general usability updates around help text, diagnostic messages
|
||||
and documentation are included as well.
|
||||
@@ -9,8 +9,8 @@ git-cat-file - Provide content or type and size information for repository objec
|
||||
SYNOPSIS
|
||||
--------
|
||||
[verse]
|
||||
'git cat-file' [-t | -s | -e | -p | <type>] <object>
|
||||
'git cat-file' [--batch | --batch-check] < <list-of-objects>
|
||||
'git cat-file' (-t | -s | -e | -p | <type>) <object>
|
||||
'git cat-file' (--batch | --batch-check) < <list-of-objects>
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
|
||||
@@ -82,8 +82,10 @@ Output Format
|
||||
-------------
|
||||
<mode> SP <type> SP <object> TAB <file>
|
||||
|
||||
When the `-z` option is not used, TAB, LF, and backslash characters
|
||||
Unless the `-z` option is used, TAB, LF, and backslash characters
|
||||
in pathnames are represented as `\t`, `\n`, and `\\`, respectively.
|
||||
This output format is compatible with what '--index-info --stdin' of
|
||||
'git update-index' expects.
|
||||
|
||||
When the `-l` option is used, format changes to
|
||||
|
||||
|
||||
@@ -75,14 +75,22 @@ show [<stash>]::
|
||||
it will accept any format known to 'git-diff' (e.g., `git stash show
|
||||
-p stash@\{1}` to view the second most recent stash in patch form).
|
||||
|
||||
pop [<stash>]::
|
||||
|
||||
Remove a single stashed state from the stash list and apply it
|
||||
on top of the current working tree state, i.e., do the inverse
|
||||
operation of `git stash save`. The working directory must
|
||||
match the index.
|
||||
+
|
||||
Applying the state can fail with conflicts; in this case, it is not
|
||||
removed from the stash list. You need to resolve the conflicts by hand
|
||||
and call `git stash drop` manually afterwards.
|
||||
+
|
||||
When no `<stash>` is given, `stash@\{0}` is assumed. See also `apply`.
|
||||
|
||||
apply [--index] [<stash>]::
|
||||
|
||||
Restore the changes recorded in the stash on top of the current
|
||||
working tree state. When no `<stash>` is given, applies the latest
|
||||
one. The working directory must match the index.
|
||||
+
|
||||
This operation can fail with conflicts; you need to resolve them
|
||||
by hand in the working tree.
|
||||
Like `pop`, but do not remove the state from the stash list.
|
||||
+
|
||||
If the `--index` option is used, then tries to reinstate not only the working
|
||||
tree's changes, but also the index's ones. However, this can fail, when you
|
||||
@@ -112,12 +120,6 @@ drop [<stash>]::
|
||||
Remove a single stashed state from the stash list. When no `<stash>`
|
||||
is given, it removes the latest one. i.e. `stash@\{0}`
|
||||
|
||||
pop [<stash>]::
|
||||
|
||||
Remove a single stashed state from the stash list and apply on top
|
||||
of the current working tree state. When no `<stash>` is given,
|
||||
`stash@\{0}` is assumed. See also `apply`.
|
||||
|
||||
create::
|
||||
|
||||
Create a stash (which is a regular commit object) and return its
|
||||
@@ -163,7 +165,7 @@ $ git pull
|
||||
file foobar not up to date, cannot merge.
|
||||
$ git stash
|
||||
$ git pull
|
||||
$ git stash apply
|
||||
$ git stash pop
|
||||
----------------------------------------------------------------
|
||||
|
||||
Interrupted workflow::
|
||||
@@ -192,7 +194,7 @@ You can use 'git-stash' to simplify the above, like this:
|
||||
$ git stash
|
||||
$ edit emergency fix
|
||||
$ git commit -a -m "Fix in a hurry"
|
||||
$ git stash apply
|
||||
$ git stash pop
|
||||
# ... continue hacking ...
|
||||
----------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -39,7 +39,8 @@
|
||||
|
||||
--squash::
|
||||
Produce the working tree and index state as if a real
|
||||
merge happened, but do not actually make a commit or
|
||||
merge happened (except for the merge information),
|
||||
but do not actually make a commit or
|
||||
move the `HEAD`, nor record `$GIT_DIR/MERGE_HEAD` to
|
||||
cause the next `git commit` command to create a merge
|
||||
commit. This allows you to create a single commit on
|
||||
|
||||
@@ -198,7 +198,7 @@ The function must be defined in this form:
|
||||
|
||||
The callback mechanism is as follows:
|
||||
|
||||
* Inside `funct`, the only interesting member of the structure
|
||||
* Inside `func`, the only interesting member of the structure
|
||||
given by `opt` is the void pointer `opt->value`.
|
||||
`\*opt->value` will be the value that is saved into `var`, if you
|
||||
use `OPT_CALLBACK()`.
|
||||
|
||||
@@ -1520,10 +1520,10 @@ $ git commit -a -m "blorpl: typofix"
|
||||
------------------------------------------------
|
||||
|
||||
After that, you can go back to what you were working on with
|
||||
`git stash apply`:
|
||||
`git stash pop`:
|
||||
|
||||
------------------------------------------------
|
||||
$ git stash apply
|
||||
$ git stash pop
|
||||
------------------------------------------------
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/bin/sh
|
||||
|
||||
GVF=GIT-VERSION-FILE
|
||||
DEF_VER=v1.6.3.1
|
||||
DEF_VER=v1.6.3.2
|
||||
|
||||
LF='
|
||||
'
|
||||
|
||||
5
Makefile
5
Makefile
@@ -176,6 +176,9 @@ all::
|
||||
# when hardlinking a file to another name and unlinking the original file right
|
||||
# away (some NTFS drivers seem to zero the contents in that scenario).
|
||||
#
|
||||
# Define NO_CROSS_DIRECTORY_HARDLINKS if you plan to distribute the installed
|
||||
# programs as a tar, where bin/ and libexec/ might be on different file systems.
|
||||
#
|
||||
# Define USE_NED_ALLOCATOR if you want to replace the platforms default
|
||||
# memory allocators with the nedmalloc allocator written by Niall Douglas.
|
||||
|
||||
@@ -753,6 +756,7 @@ endif
|
||||
ifeq ($(uname_S),OpenBSD)
|
||||
NO_STRCASESTR = YesPlease
|
||||
NO_MEMMEM = YesPlease
|
||||
USE_ST_TIMESPEC = YesPlease
|
||||
NEEDS_LIBICONV = YesPlease
|
||||
BASIC_CFLAGS += -I/usr/local/include
|
||||
BASIC_LDFLAGS += -L/usr/local/lib
|
||||
@@ -1569,6 +1573,7 @@ endif
|
||||
bindir=$$(cd '$(DESTDIR_SQ)$(bindir_SQ)' && pwd) && \
|
||||
execdir=$$(cd '$(DESTDIR_SQ)$(gitexec_instdir_SQ)' && pwd) && \
|
||||
{ $(RM) "$$execdir/git-add$X" && \
|
||||
test -z "$(NO_CROSS_DIRECTORY_HARDLINKS)" && \
|
||||
ln "$$bindir/git$X" "$$execdir/git-add$X" 2>/dev/null || \
|
||||
cp "$$bindir/git$X" "$$execdir/git-add$X"; } && \
|
||||
{ for p in $(filter-out git-add$X,$(BUILT_INS)); do \
|
||||
|
||||
2
RelNotes
2
RelNotes
@@ -1 +1 @@
|
||||
Documentation/RelNotes-1.6.3.1.txt
|
||||
Documentation/RelNotes-1.6.3.2.txt
|
||||
8
alias.c
8
alias.c
@@ -38,10 +38,7 @@ int split_cmdline(char *cmdline, const char ***argv)
|
||||
while (cmdline[++src]
|
||||
&& isspace(cmdline[src]))
|
||||
; /* skip */
|
||||
if (count >= size) {
|
||||
size += 16;
|
||||
*argv = xrealloc(*argv, sizeof(char *) * size);
|
||||
}
|
||||
ALLOC_GROW(*argv, count+1, size);
|
||||
(*argv)[count++] = cmdline + dst;
|
||||
} else if (!quoted && (c == '\'' || c == '"')) {
|
||||
quoted = c;
|
||||
@@ -72,6 +69,9 @@ int split_cmdline(char *cmdline, const char ***argv)
|
||||
return error("unclosed quote");
|
||||
}
|
||||
|
||||
ALLOC_GROW(*argv, count+1, size);
|
||||
(*argv)[count] = NULL;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ static void prune_directory(struct dir_struct *dir, const char **pathspec, int p
|
||||
fill_pathspec_matches(pathspec, seen, specs);
|
||||
|
||||
for (i = 0; i < specs; i++) {
|
||||
if (!seen[i] && !file_exists(pathspec[i]))
|
||||
if (!seen[i] && pathspec[i][0] && !file_exists(pathspec[i]))
|
||||
die("pathspec '%s' did not match any files",
|
||||
pathspec[i]);
|
||||
}
|
||||
|
||||
@@ -2781,7 +2781,7 @@ static void remove_file(struct patch *patch, int rmdir_empty)
|
||||
if (rmdir(patch->old_name))
|
||||
warning("unable to remove submodule %s",
|
||||
patch->old_name);
|
||||
} else if (!unlink(patch->old_name) && rmdir_empty) {
|
||||
} else if (!unlink_or_warn(patch->old_name) && rmdir_empty) {
|
||||
remove_path(patch->old_name);
|
||||
}
|
||||
}
|
||||
@@ -2891,7 +2891,7 @@ static void create_one_file(char *path, unsigned mode, const char *buf, unsigned
|
||||
if (!try_create_file(newpath, mode, buf, size)) {
|
||||
if (!rename(newpath, path))
|
||||
return;
|
||||
unlink(newpath);
|
||||
unlink_or_warn(newpath);
|
||||
break;
|
||||
}
|
||||
if (errno != EEXIST)
|
||||
@@ -3315,6 +3315,10 @@ int cmd_apply(int argc, const char **argv, const char *unused_prefix)
|
||||
|
||||
argc = parse_options(argc, argv, builtin_apply_options,
|
||||
apply_usage, 0);
|
||||
fake_ancestor = parse_options_fix_filename(prefix, fake_ancestor);
|
||||
if (fake_ancestor)
|
||||
fake_ancestor = xstrdup(fake_ancestor);
|
||||
|
||||
if (apply_with_reject)
|
||||
apply = apply_verbosely = 1;
|
||||
if (!force_apply && (diffstat || numstat || summary || check || fake_ancestor))
|
||||
|
||||
@@ -362,18 +362,28 @@ static struct origin *find_origin(struct scoreboard *sb,
|
||||
"", &diff_opts);
|
||||
diffcore_std(&diff_opts);
|
||||
|
||||
/* It is either one entry that says "modified", or "created",
|
||||
* or nothing.
|
||||
*/
|
||||
if (!diff_queued_diff.nr) {
|
||||
/* The path is the same as parent */
|
||||
porigin = get_origin(sb, parent, origin->path);
|
||||
hashcpy(porigin->blob_sha1, origin->blob_sha1);
|
||||
}
|
||||
else if (diff_queued_diff.nr != 1)
|
||||
die("internal error in blame::find_origin");
|
||||
else {
|
||||
struct diff_filepair *p = diff_queued_diff.queue[0];
|
||||
} else {
|
||||
/*
|
||||
* Since origin->path is a pathspec, if the parent
|
||||
* commit had it as a directory, we will see a whole
|
||||
* bunch of deletion of files in the directory that we
|
||||
* do not care about.
|
||||
*/
|
||||
int i;
|
||||
struct diff_filepair *p = NULL;
|
||||
for (i = 0; i < diff_queued_diff.nr; i++) {
|
||||
const char *name;
|
||||
p = diff_queued_diff.queue[i];
|
||||
name = p->one->path ? p->one->path : p->two->path;
|
||||
if (!strcmp(name, origin->path))
|
||||
break;
|
||||
}
|
||||
if (!p)
|
||||
die("internal error in blame::find_origin");
|
||||
switch (p->status) {
|
||||
default:
|
||||
die("internal error in blame::find_origin (%c)",
|
||||
|
||||
@@ -201,8 +201,8 @@ static int batch_objects(int print_contents)
|
||||
}
|
||||
|
||||
static const char * const cat_file_usage[] = {
|
||||
"git cat-file [-t|-s|-e|-p|<type>] <sha1>",
|
||||
"git cat-file [--batch|--batch-check] < <list_of_sha1s>",
|
||||
"git cat-file (-t|-s|-e|-p|<type>) <object>",
|
||||
"git cat-file (--batch|--batch-check) < <list_of_objects>",
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
@@ -216,7 +216,7 @@ static int checkout_paths(struct tree *source_tree, const char **pathspec,
|
||||
struct lock_file *lock_file = xcalloc(1, sizeof(struct lock_file));
|
||||
|
||||
newfd = hold_locked_index(lock_file, 1);
|
||||
if (read_cache() < 0)
|
||||
if (read_cache_preload(pathspec) < 0)
|
||||
return error("corrupt index file");
|
||||
|
||||
if (source_tree)
|
||||
@@ -366,7 +366,7 @@ static int merge_working_tree(struct checkout_opts *opts,
|
||||
struct lock_file *lock_file = xcalloc(1, sizeof(struct lock_file));
|
||||
int newfd = hold_locked_index(lock_file, 1);
|
||||
|
||||
if (read_cache() < 0)
|
||||
if (read_cache_preload(NULL) < 0)
|
||||
return error("corrupt index file");
|
||||
|
||||
if (opts->force) {
|
||||
@@ -541,14 +541,6 @@ static int switch_branches(struct checkout_opts *opts, struct branch_info *new)
|
||||
parse_commit(new->commit);
|
||||
}
|
||||
|
||||
/*
|
||||
* If we were on a detached HEAD, but we are now moving to
|
||||
* a new commit, we want to mention the old commit once more
|
||||
* to remind the user that it might be lost.
|
||||
*/
|
||||
if (!opts->quiet && !old.path && old.commit && new->commit != old.commit)
|
||||
describe_detached_head("Previous HEAD position was", old.commit);
|
||||
|
||||
if (!old.commit && !opts->force) {
|
||||
if (!opts->quiet) {
|
||||
warning("You appear to be on a branch yet to be born.");
|
||||
@@ -561,6 +553,14 @@ static int switch_branches(struct checkout_opts *opts, struct branch_info *new)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* If we were on a detached HEAD, but have now moved to
|
||||
* a new commit, we want to mention the old commit once more
|
||||
* to remind the user that it might be lost.
|
||||
*/
|
||||
if (!opts->quiet && !old.path && old.commit && new->commit != old.commit)
|
||||
describe_detached_head("Previous HEAD position was", old.commit);
|
||||
|
||||
update_refs_for_switch(opts, &old, new);
|
||||
|
||||
ret = post_checkout_hook(old.commit, new->commit, 1);
|
||||
|
||||
@@ -228,7 +228,8 @@ static void copy_or_link_directory(struct strbuf *src, struct strbuf *dest)
|
||||
}
|
||||
|
||||
if (unlink(dest->buf) && errno != ENOENT)
|
||||
die("failed to unlink %s", dest->buf);
|
||||
die("failed to unlink %s: %s",
|
||||
dest->buf, strerror(errno));
|
||||
if (!option_no_hardlinks) {
|
||||
if (!link(src->buf, dest->buf))
|
||||
continue;
|
||||
|
||||
@@ -699,7 +699,11 @@ static int parse_and_validate_options(int argc, const char *argv[],
|
||||
|
||||
argc = parse_options(argc, argv, builtin_commit_options, usage, 0);
|
||||
logfile = parse_options_fix_filename(prefix, logfile);
|
||||
if (logfile)
|
||||
logfile = xstrdup(logfile);
|
||||
template_file = parse_options_fix_filename(prefix, template_file);
|
||||
if (template_file)
|
||||
template_file = xstrdup(template_file);
|
||||
|
||||
if (force_author && !strchr(force_author, '>'))
|
||||
force_author = find_author_by_nickname(force_author);
|
||||
|
||||
@@ -825,7 +825,7 @@ struct ref *fetch_pack(struct fetch_pack_args *my_args,
|
||||
fd = hold_lock_file_for_update(&lock, shallow,
|
||||
LOCK_DIE_ON_ERROR);
|
||||
if (!write_shallow_commits(fd, 0)) {
|
||||
unlink(shallow);
|
||||
unlink_or_warn(shallow);
|
||||
rollback_lock_file(&lock);
|
||||
} else {
|
||||
commit_lock_file(&lock);
|
||||
|
||||
@@ -167,6 +167,9 @@ static struct ref *get_ref_map(struct transport *transport,
|
||||
return ref_map;
|
||||
}
|
||||
|
||||
#define STORE_REF_ERROR_OTHER 1
|
||||
#define STORE_REF_ERROR_DF_CONFLICT 2
|
||||
|
||||
static int s_update_ref(const char *action,
|
||||
struct ref *ref,
|
||||
int check_old)
|
||||
@@ -181,9 +184,11 @@ static int s_update_ref(const char *action,
|
||||
lock = lock_any_ref_for_update(ref->name,
|
||||
check_old ? ref->old_sha1 : NULL, 0);
|
||||
if (!lock)
|
||||
return 2;
|
||||
return errno == ENOTDIR ? STORE_REF_ERROR_DF_CONFLICT :
|
||||
STORE_REF_ERROR_OTHER;
|
||||
if (write_ref_sha1(lock, ref->new_sha1, msg) < 0)
|
||||
return 2;
|
||||
return errno == ENOTDIR ? STORE_REF_ERROR_DF_CONFLICT :
|
||||
STORE_REF_ERROR_OTHER;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -377,7 +382,7 @@ static int store_updated_refs(const char *url, const char *remote_name,
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
if (rc & 2)
|
||||
if (rc & STORE_REF_ERROR_DF_CONFLICT)
|
||||
error("some local refs could not be updated; try running\n"
|
||||
" 'git remote prune %s' to remove any old, conflicting "
|
||||
"branches", remote_name);
|
||||
|
||||
@@ -363,6 +363,7 @@ int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix)
|
||||
argc = parse_options(argc, argv, options, fmt_merge_msg_usage, 0);
|
||||
if (argc > 0)
|
||||
usage_with_options(fmt_merge_msg_usage, options);
|
||||
inpath = parse_options_fix_filename(prefix, inpath);
|
||||
|
||||
if (inpath && strcmp(inpath, "-")) {
|
||||
in = fopen(inpath, "r");
|
||||
|
||||
@@ -339,8 +339,11 @@ static const char *copy_name(const char *buf)
|
||||
static const char *copy_email(const char *buf)
|
||||
{
|
||||
const char *email = strchr(buf, '<');
|
||||
const char *eoemail = strchr(email, '>');
|
||||
if (!email || !eoemail)
|
||||
const char *eoemail;
|
||||
if (!email)
|
||||
return "";
|
||||
eoemail = strchr(email, '>');
|
||||
if (!eoemail)
|
||||
return "";
|
||||
return xmemdupz(email, eoemail + 1 - email);
|
||||
}
|
||||
|
||||
@@ -755,6 +755,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
|
||||
int cover_letter = 0;
|
||||
int boundary_count = 0;
|
||||
int no_binary_diff = 0;
|
||||
int numbered_cmdline_opt = 0;
|
||||
struct commit *origin = NULL, *head = NULL;
|
||||
const char *in_reply_to = NULL;
|
||||
struct patch_ids ids;
|
||||
@@ -786,8 +787,10 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
|
||||
if (!strcmp(argv[i], "--stdout"))
|
||||
use_stdout = 1;
|
||||
else if (!strcmp(argv[i], "-n") ||
|
||||
!strcmp(argv[i], "--numbered"))
|
||||
!strcmp(argv[i], "--numbered")) {
|
||||
numbered = 1;
|
||||
numbered_cmdline_opt = 1;
|
||||
}
|
||||
else if (!strcmp(argv[i], "-N") ||
|
||||
!strcmp(argv[i], "--no-numbered")) {
|
||||
numbered = 0;
|
||||
@@ -918,6 +921,15 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
|
||||
|
||||
if (start_number < 0)
|
||||
start_number = 1;
|
||||
|
||||
/*
|
||||
* If numbered is set solely due to format.numbered in config,
|
||||
* and it would conflict with --keep-subject (-k) from the
|
||||
* command line, reset "numbered".
|
||||
*/
|
||||
if (numbered && keep_subject && !numbered_cmdline_opt)
|
||||
numbered = 0;
|
||||
|
||||
if (numbered && keep_subject)
|
||||
die ("-n and -k are mutually exclusive.");
|
||||
if (keep_subject && subject_prefix)
|
||||
|
||||
@@ -28,8 +28,8 @@ static void prune_dir(int i, DIR *dir, char *pathname, int len, int opts)
|
||||
memcpy(pathname + len, de->d_name, 38);
|
||||
if (opts & DRY_RUN)
|
||||
printf("rm -f %s\n", pathname);
|
||||
else if (unlink(pathname) < 0)
|
||||
error("unable to unlink %s", pathname);
|
||||
else
|
||||
unlink_or_warn(pathname);
|
||||
display_progress(progress, i + 1);
|
||||
}
|
||||
pathname[len] = 0;
|
||||
|
||||
@@ -27,7 +27,7 @@ static int prune_tmp_object(const char *path, const char *filename)
|
||||
}
|
||||
printf("Removing stale temporary file %s\n", fullpath);
|
||||
if (!show_only)
|
||||
unlink(fullpath);
|
||||
unlink_or_warn(fullpath);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ static int prune_object(char *path, const char *filename, const unsigned char *s
|
||||
(type > 0) ? typename(type) : "unknown");
|
||||
}
|
||||
if (!show_only)
|
||||
unlink(fullpath);
|
||||
unlink_or_warn(fullpath);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,10 +27,9 @@ static int receive_unpack_limit = -1;
|
||||
static int transfer_unpack_limit = -1;
|
||||
static int unpack_limit = 100;
|
||||
static int report_status;
|
||||
static int prefer_ofs_delta = 1;
|
||||
static const char *head_name;
|
||||
|
||||
static char capabilities[] = " report-status delete-refs ";
|
||||
static int capabilities_sent;
|
||||
static char *capabilities_to_send;
|
||||
|
||||
static enum deny_action parse_deny_action(const char *var, const char *value)
|
||||
{
|
||||
@@ -84,24 +83,29 @@ static int receive_pack_config(const char *var, const char *value, void *cb)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (strcmp(var, "repack.usedeltabaseoffset") == 0) {
|
||||
prefer_ofs_delta = git_config_bool(var, value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return git_default_config(var, value, cb);
|
||||
}
|
||||
|
||||
static int show_ref(const char *path, const unsigned char *sha1, int flag, void *cb_data)
|
||||
{
|
||||
if (capabilities_sent)
|
||||
if (!capabilities_to_send)
|
||||
packet_write(1, "%s %s\n", sha1_to_hex(sha1), path);
|
||||
else
|
||||
packet_write(1, "%s %s%c%s\n",
|
||||
sha1_to_hex(sha1), path, 0, capabilities);
|
||||
capabilities_sent = 1;
|
||||
sha1_to_hex(sha1), path, 0, capabilities_to_send);
|
||||
capabilities_to_send = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void write_head_info(void)
|
||||
{
|
||||
for_each_ref(show_ref, NULL);
|
||||
if (!capabilities_sent)
|
||||
if (capabilities_to_send)
|
||||
show_ref("capabilities^{}", null_sha1, 0, NULL);
|
||||
|
||||
}
|
||||
@@ -687,6 +691,10 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)
|
||||
else if (0 <= receive_unpack_limit)
|
||||
unpack_limit = receive_unpack_limit;
|
||||
|
||||
capabilities_to_send = (prefer_ofs_delta) ?
|
||||
" report-status delete-refs ofs-delta " :
|
||||
" report-status delete-refs ";
|
||||
|
||||
add_alternate_refs();
|
||||
write_head_info();
|
||||
clear_extra_refs();
|
||||
@@ -702,7 +710,7 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)
|
||||
unpack_status = unpack();
|
||||
execute_commands(unpack_status);
|
||||
if (pack_lockfile)
|
||||
unlink(pack_lockfile);
|
||||
unlink_or_warn(pack_lockfile);
|
||||
if (report_status)
|
||||
report(unpack_status);
|
||||
run_receive_hook(post_receive_hook);
|
||||
|
||||
@@ -299,11 +299,11 @@ static int get_push_ref_states(const struct ref *remote_refs,
|
||||
return 0;
|
||||
|
||||
local_refs = get_local_heads();
|
||||
ref = push_map = copy_ref_list(remote_refs);
|
||||
while (ref->next)
|
||||
ref = ref->next;
|
||||
push_tail = &ref->next;
|
||||
push_map = copy_ref_list(remote_refs);
|
||||
|
||||
push_tail = &push_map;
|
||||
while (*push_tail)
|
||||
push_tail = &((*push_tail)->next);
|
||||
match_refs(local_refs, push_map, &push_tail, remote->push_refspec_nr,
|
||||
remote->push_refspec, MATCH_REFS_NONE);
|
||||
|
||||
@@ -525,8 +525,8 @@ static int migrate_file(struct remote *remote)
|
||||
path = git_path("remotes/%s", remote->name);
|
||||
else if (remote->origin == REMOTE_BRANCHES)
|
||||
path = git_path("branches/%s", remote->name);
|
||||
if (path && unlink(path))
|
||||
warning("failed to remove '%s'", path);
|
||||
if (path)
|
||||
unlink_or_warn(path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -116,7 +116,7 @@ int cmd_rerere(int argc, const char **argv, const char *prefix)
|
||||
if (!has_rerere_resolution(name))
|
||||
unlink_rr_item(name);
|
||||
}
|
||||
unlink(git_path("rr-cache/MERGE_RR"));
|
||||
unlink_or_warn(git_path("rr-cache/MERGE_RR"));
|
||||
} else if (!strcmp(argv[1], "gc"))
|
||||
garbage_collect(&merge_rr);
|
||||
else if (!strcmp(argv[1], "status"))
|
||||
|
||||
@@ -43,12 +43,16 @@ static int pack_objects(int fd, struct ref *refs, struct extra_have_objects *ext
|
||||
"--stdout",
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
};
|
||||
struct child_process po;
|
||||
int i;
|
||||
|
||||
i = 4;
|
||||
if (args->use_thin_pack)
|
||||
argv[4] = "--thin";
|
||||
argv[i++] = "--thin";
|
||||
if (args->use_ofs_delta)
|
||||
argv[i++] = "--delta-base-offset";
|
||||
memset(&po, 0, sizeof(po));
|
||||
po.argv = argv;
|
||||
po.in = -1;
|
||||
@@ -315,6 +319,8 @@ int send_pack(struct send_pack_args *args,
|
||||
ask_for_status_report = 1;
|
||||
if (server_supports("delete-refs"))
|
||||
allow_deleting_refs = 1;
|
||||
if (server_supports("ofs-delta"))
|
||||
args->use_ofs_delta = 1;
|
||||
|
||||
if (!remote_refs) {
|
||||
fprintf(stderr, "No refs in common and none specified; doing nothing.\n"
|
||||
|
||||
@@ -576,7 +576,7 @@ static void parse_reflog_param(const char *arg, int *cnt, const char **base)
|
||||
if (*ep == ',')
|
||||
*base = ep + 1;
|
||||
else if (*ep)
|
||||
die("unrecognized reflog param '%s'", arg + 9);
|
||||
die("unrecognized reflog param '%s'", arg);
|
||||
else
|
||||
*base = NULL;
|
||||
if (*cnt <= 0)
|
||||
|
||||
@@ -338,7 +338,7 @@ static void create_tag(const unsigned char *object, const char *tag,
|
||||
exit(128);
|
||||
}
|
||||
if (path) {
|
||||
unlink(path);
|
||||
unlink_or_warn(path);
|
||||
free(path);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ static int run_gpg_verify(const char *buf, unsigned long size, int verbose)
|
||||
close(gpg.in);
|
||||
ret = finish_command(&gpg);
|
||||
|
||||
unlink(path);
|
||||
unlink_or_warn(path);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -99,20 +99,32 @@ __git_ps1 ()
|
||||
elif [ -d "$g/rebase-merge" ]; then
|
||||
r="|REBASE-m"
|
||||
b="$(cat "$g/rebase-merge/head-name")"
|
||||
elif [ -f "$g/MERGE_HEAD" ]; then
|
||||
r="|MERGING"
|
||||
b="$(git symbolic-ref HEAD 2>/dev/null)"
|
||||
else
|
||||
if [ -f "$g/MERGE_HEAD" ]; then
|
||||
r="|MERGING"
|
||||
fi
|
||||
if [ -f "$g/BISECT_LOG" ]; then
|
||||
r="|BISECTING"
|
||||
fi
|
||||
if ! b="$(git symbolic-ref HEAD 2>/dev/null)"; then
|
||||
if ! b="$(git describe --exact-match HEAD 2>/dev/null)"; then
|
||||
if [ -r "$g/HEAD" ]; then
|
||||
b="$(cut -c1-7 "$g/HEAD")..."
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
b="$(git symbolic-ref HEAD 2>/dev/null)" || {
|
||||
|
||||
b="$(
|
||||
case "${GIT_PS1_DESCRIBE_STYLE-}" in
|
||||
(contains)
|
||||
git describe --contains HEAD ;;
|
||||
(branch)
|
||||
git describe --contains --all HEAD ;;
|
||||
(describe)
|
||||
git describe HEAD ;;
|
||||
(* | default)
|
||||
git describe --exact-match HEAD ;;
|
||||
esac 2>/dev/null)" ||
|
||||
|
||||
b="$(cut -c1-7 "$g/HEAD" 2>/dev/null)..." ||
|
||||
b="unknown"
|
||||
b="($b)"
|
||||
}
|
||||
fi
|
||||
|
||||
local w
|
||||
@@ -120,7 +132,7 @@ __git_ps1 ()
|
||||
local c
|
||||
|
||||
if [ "true" = "$(git rev-parse --is-inside-git-dir 2>/dev/null)" ]; then
|
||||
if [ "true" = "$(git config --bool core.bare 2>/dev/null)" ]; then
|
||||
if [ "true" = "$(git rev-parse --is-bare-repository 2>/dev/null)" ]; then
|
||||
c="BARE:"
|
||||
else
|
||||
b="GIT_DIR!"
|
||||
@@ -1792,7 +1804,7 @@ _git_show ()
|
||||
return
|
||||
;;
|
||||
--*)
|
||||
__gitcomp "--pretty= --format=
|
||||
__gitcomp "--pretty= --format= --abbrev-commit --oneline
|
||||
$__git_diff_common_options
|
||||
"
|
||||
return
|
||||
@@ -1809,7 +1821,7 @@ _git_show_branch ()
|
||||
__gitcomp "
|
||||
--all --remotes --topo-order --current --more=
|
||||
--list --independent --merge-base --no-name
|
||||
--sha1-name --topics --reflog
|
||||
--sha1-name --sparse --topics --reflog
|
||||
"
|
||||
return
|
||||
;;
|
||||
|
||||
@@ -8,8 +8,9 @@
|
||||
|
||||
static unsigned int hash_obj(const struct object *obj, unsigned int n)
|
||||
{
|
||||
const void *p = obj->sha1;
|
||||
unsigned int hash = *(const unsigned int *)p;
|
||||
unsigned int hash;
|
||||
|
||||
memcpy(&hash, obj->sha1, sizeof(unsigned int));
|
||||
return hash % n;
|
||||
}
|
||||
|
||||
|
||||
@@ -214,7 +214,7 @@ static int get_stat_data(struct cache_entry *ce,
|
||||
const unsigned char *sha1 = ce->sha1;
|
||||
unsigned int mode = ce->ce_mode;
|
||||
|
||||
if (!cached) {
|
||||
if (!cached && !ce_uptodate(ce)) {
|
||||
int changed;
|
||||
struct stat st;
|
||||
changed = check_removed(ce, &st);
|
||||
|
||||
2
diff.c
2
diff.c
@@ -189,7 +189,7 @@ static void remove_tempfile(void)
|
||||
int i;
|
||||
for (i = 0; i < ARRAY_SIZE(diff_temp); i++) {
|
||||
if (diff_temp[i].name == diff_temp[i].tmp_path)
|
||||
unlink(diff_temp[i].name);
|
||||
unlink_or_warn(diff_temp[i].name);
|
||||
diff_temp[i].name = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
2
dir.c
2
dir.c
@@ -576,7 +576,7 @@ static int get_dtype(struct dirent *de, const char *path)
|
||||
*/
|
||||
static int read_directory_recursive(struct dir_struct *dir, const char *path, const char *base, int baselen, int check_only, const struct path_simplify *simplify)
|
||||
{
|
||||
DIR *fdir = opendir(path);
|
||||
DIR *fdir = opendir(*path ? path : ".");
|
||||
int contents = 0;
|
||||
|
||||
if (fdir) {
|
||||
|
||||
2
entry.c
2
entry.c
@@ -35,7 +35,7 @@ static void create_directories(const char *path, int path_len,
|
||||
*/
|
||||
if (mkdir(buf, 0777)) {
|
||||
if (errno == EEXIST && state->force &&
|
||||
!unlink(buf) && !mkdir(buf, 0777))
|
||||
!unlink_or_warn(buf) && !mkdir(buf, 0777))
|
||||
continue;
|
||||
die("cannot create directory at %s", buf);
|
||||
}
|
||||
|
||||
@@ -931,7 +931,7 @@ static void unkeep_all_packs(void)
|
||||
struct packed_git *p = all_packs[k];
|
||||
snprintf(name, sizeof(name), "%s/pack/pack-%s.keep",
|
||||
get_object_directory(), sha1_to_hex(p->sha1));
|
||||
unlink(name);
|
||||
unlink_or_warn(name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -981,7 +981,7 @@ static void end_packfile(void)
|
||||
}
|
||||
else {
|
||||
close(old_p->pack_fd);
|
||||
unlink(old_p->pack_name);
|
||||
unlink_or_warn(old_p->pack_name);
|
||||
}
|
||||
free(old_p);
|
||||
|
||||
|
||||
@@ -767,6 +767,96 @@ sub split_hunk {
|
||||
return @split;
|
||||
}
|
||||
|
||||
sub find_last_o_ctx {
|
||||
my ($it) = @_;
|
||||
my $text = $it->{TEXT};
|
||||
my ($o_ofs, $o_cnt) = parse_hunk_header($text->[0]);
|
||||
my $i = @{$text};
|
||||
my $last_o_ctx = $o_ofs + $o_cnt;
|
||||
while (0 < --$i) {
|
||||
my $line = $text->[$i];
|
||||
if ($line =~ /^ /) {
|
||||
$last_o_ctx--;
|
||||
next;
|
||||
}
|
||||
last;
|
||||
}
|
||||
return $last_o_ctx;
|
||||
}
|
||||
|
||||
sub merge_hunk {
|
||||
my ($prev, $this) = @_;
|
||||
my ($o0_ofs, $o0_cnt, $n0_ofs, $n0_cnt) =
|
||||
parse_hunk_header($prev->{TEXT}[0]);
|
||||
my ($o1_ofs, $o1_cnt, $n1_ofs, $n1_cnt) =
|
||||
parse_hunk_header($this->{TEXT}[0]);
|
||||
|
||||
my (@line, $i, $ofs, $o_cnt, $n_cnt);
|
||||
$ofs = $o0_ofs;
|
||||
$o_cnt = $n_cnt = 0;
|
||||
for ($i = 1; $i < @{$prev->{TEXT}}; $i++) {
|
||||
my $line = $prev->{TEXT}[$i];
|
||||
if ($line =~ /^\+/) {
|
||||
$n_cnt++;
|
||||
push @line, $line;
|
||||
next;
|
||||
}
|
||||
|
||||
last if ($o1_ofs <= $ofs);
|
||||
|
||||
$o_cnt++;
|
||||
$ofs++;
|
||||
if ($line =~ /^ /) {
|
||||
$n_cnt++;
|
||||
}
|
||||
push @line, $line;
|
||||
}
|
||||
|
||||
for ($i = 1; $i < @{$this->{TEXT}}; $i++) {
|
||||
my $line = $this->{TEXT}[$i];
|
||||
if ($line =~ /^\+/) {
|
||||
$n_cnt++;
|
||||
push @line, $line;
|
||||
next;
|
||||
}
|
||||
$ofs++;
|
||||
$o_cnt++;
|
||||
if ($line =~ /^ /) {
|
||||
$n_cnt++;
|
||||
}
|
||||
push @line, $line;
|
||||
}
|
||||
my $head = ("@@ -$o0_ofs" .
|
||||
(($o_cnt != 1) ? ",$o_cnt" : '') .
|
||||
" +$n0_ofs" .
|
||||
(($n_cnt != 1) ? ",$n_cnt" : '') .
|
||||
" @@\n");
|
||||
@{$prev->{TEXT}} = ($head, @line);
|
||||
}
|
||||
|
||||
sub coalesce_overlapping_hunks {
|
||||
my (@in) = @_;
|
||||
my @out = ();
|
||||
|
||||
my ($last_o_ctx, $last_was_dirty);
|
||||
|
||||
for (grep { $_->{USE} } @in) {
|
||||
my $text = $_->{TEXT};
|
||||
my ($o_ofs) = parse_hunk_header($text->[0]);
|
||||
if (defined $last_o_ctx &&
|
||||
$o_ofs <= $last_o_ctx &&
|
||||
!$_->{DIRTY} &&
|
||||
!$last_was_dirty) {
|
||||
merge_hunk($out[-1], $_);
|
||||
}
|
||||
else {
|
||||
push @out, $_;
|
||||
}
|
||||
$last_o_ctx = find_last_o_ctx($out[-1]);
|
||||
$last_was_dirty = $_->{DIRTY};
|
||||
}
|
||||
return @out;
|
||||
}
|
||||
|
||||
sub color_diff {
|
||||
return map {
|
||||
@@ -878,7 +968,8 @@ sub edit_hunk_loop {
|
||||
my $newhunk = {
|
||||
TEXT => $text,
|
||||
TYPE => $hunk->[$ix]->{TYPE},
|
||||
USE => 1
|
||||
USE => 1,
|
||||
DIRTY => 1,
|
||||
};
|
||||
if (diff_applies($head,
|
||||
@{$hunk}[0..$ix-1],
|
||||
@@ -1210,6 +1301,8 @@ sub patch_update_file {
|
||||
}
|
||||
}
|
||||
|
||||
@hunk = coalesce_overlapping_hunks(@hunk);
|
||||
|
||||
my $n_lofs = 0;
|
||||
my @result = ();
|
||||
for (@hunk) {
|
||||
|
||||
@@ -415,4 +415,10 @@ void git_qsort(void *base, size_t nmemb, size_t size,
|
||||
#define fstat_is_reliable() 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Preserves errno, prints a message, but gives no warning for ENOENT.
|
||||
* Always returns the return value of unlink(2).
|
||||
*/
|
||||
int unlink_or_warn(const char *path);
|
||||
|
||||
#endif
|
||||
|
||||
14
grep.c
14
grep.c
@@ -305,6 +305,7 @@ static int match_one_pattern(struct grep_pat *p, char *bol, char *eol,
|
||||
{
|
||||
int hit = 0;
|
||||
int saved_ch = 0;
|
||||
const char *start = bol;
|
||||
|
||||
if ((p->token != GREP_PATTERN) &&
|
||||
((p->token == GREP_PATTERN_HEAD) != (ctx == GREP_CONTEXT_HEAD)))
|
||||
@@ -330,7 +331,7 @@ static int match_one_pattern(struct grep_pat *p, char *bol, char *eol,
|
||||
|
||||
if (hit && p->word_regexp) {
|
||||
if ((pmatch[0].rm_so < 0) ||
|
||||
(eol - bol) <= pmatch[0].rm_so ||
|
||||
(eol - bol) < pmatch[0].rm_so ||
|
||||
(pmatch[0].rm_eo < 0) ||
|
||||
(eol - bol) < pmatch[0].rm_eo)
|
||||
die("regexp returned nonsense");
|
||||
@@ -349,6 +350,10 @@ static int match_one_pattern(struct grep_pat *p, char *bol, char *eol,
|
||||
else
|
||||
hit = 0;
|
||||
|
||||
/* Words consist of at least one character. */
|
||||
if (pmatch->rm_so == pmatch->rm_eo)
|
||||
hit = 0;
|
||||
|
||||
if (!hit && pmatch[0].rm_so + bol + 1 < eol) {
|
||||
/* There could be more than one match on the
|
||||
* line, and the first match might not be
|
||||
@@ -359,12 +364,17 @@ static int match_one_pattern(struct grep_pat *p, char *bol, char *eol,
|
||||
bol = pmatch[0].rm_so + bol + 1;
|
||||
while (word_char(bol[-1]) && bol < eol)
|
||||
bol++;
|
||||
eflags |= REG_NOTBOL;
|
||||
if (bol < eol)
|
||||
goto again;
|
||||
}
|
||||
}
|
||||
if (p->token == GREP_PATTERN_HEAD && saved_ch)
|
||||
*eol = saved_ch;
|
||||
if (hit) {
|
||||
pmatch[0].rm_so += bol - start;
|
||||
pmatch[0].rm_eo += bol - start;
|
||||
}
|
||||
return hit;
|
||||
}
|
||||
|
||||
@@ -494,6 +504,8 @@ static void show_line(struct grep_opt *opt, char *bol, char *eol,
|
||||
|
||||
*eol = '\0';
|
||||
while (next_match(opt, bol, eol, ctx, &match, eflags)) {
|
||||
if (match.rm_so == match.rm_eo)
|
||||
break;
|
||||
printf("%.*s%s%.*s%s",
|
||||
(int)match.rm_so, bol,
|
||||
opt->color_match,
|
||||
|
||||
15
http-push.c
15
http-push.c
@@ -315,9 +315,9 @@ static void start_fetch_loose(struct transfer_request *request)
|
||||
"%s.temp", filename);
|
||||
|
||||
snprintf(prevfile, sizeof(prevfile), "%s.prev", request->filename);
|
||||
unlink(prevfile);
|
||||
unlink_or_warn(prevfile);
|
||||
rename(request->tmpfile, prevfile);
|
||||
unlink(request->tmpfile);
|
||||
unlink_or_warn(request->tmpfile);
|
||||
|
||||
if (request->local_fileno != -1)
|
||||
error("fd leakage in start: %d", request->local_fileno);
|
||||
@@ -372,7 +372,7 @@ static void start_fetch_loose(struct transfer_request *request)
|
||||
} while (prev_read > 0);
|
||||
close(prevlocal);
|
||||
}
|
||||
unlink(prevfile);
|
||||
unlink_or_warn(prevfile);
|
||||
|
||||
/* Reset inflate/SHA1 if there was an error reading the previous temp
|
||||
file; also rewind to the beginning of the local file. */
|
||||
@@ -784,7 +784,7 @@ static void finish_request(struct transfer_request *request)
|
||||
request->http_code != 416) {
|
||||
if (stat(request->tmpfile, &st) == 0) {
|
||||
if (st.st_size == 0)
|
||||
unlink(request->tmpfile);
|
||||
unlink_or_warn(request->tmpfile);
|
||||
}
|
||||
} else {
|
||||
if (request->http_code == 416)
|
||||
@@ -793,9 +793,9 @@ static void finish_request(struct transfer_request *request)
|
||||
git_inflate_end(&request->stream);
|
||||
git_SHA1_Final(request->real_sha1, &request->c);
|
||||
if (request->zret != Z_STREAM_END) {
|
||||
unlink(request->tmpfile);
|
||||
unlink_or_warn(request->tmpfile);
|
||||
} else if (hashcmp(request->obj->sha1, request->real_sha1)) {
|
||||
unlink(request->tmpfile);
|
||||
unlink_or_warn(request->tmpfile);
|
||||
} else {
|
||||
request->rename =
|
||||
move_temp_to_file(
|
||||
@@ -1415,8 +1415,9 @@ static void remove_locks(void)
|
||||
|
||||
fprintf(stderr, "Removing remote locks...\n");
|
||||
while (lock) {
|
||||
struct remote_lock *next = lock->next;
|
||||
unlock_remote(lock);
|
||||
lock = lock->next;
|
||||
lock = next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -111,9 +111,9 @@ static void start_object_request(struct walker *walker,
|
||||
struct walker_data *data = walker->data;
|
||||
|
||||
snprintf(prevfile, sizeof(prevfile), "%s.prev", obj_req->filename);
|
||||
unlink(prevfile);
|
||||
unlink_or_warn(prevfile);
|
||||
rename(obj_req->tmpfile, prevfile);
|
||||
unlink(obj_req->tmpfile);
|
||||
unlink_or_warn(obj_req->tmpfile);
|
||||
|
||||
if (obj_req->local != -1)
|
||||
error("fd leakage in start: %d", obj_req->local);
|
||||
@@ -177,7 +177,7 @@ static void start_object_request(struct walker *walker,
|
||||
} while (prev_read > 0);
|
||||
close(prevlocal);
|
||||
}
|
||||
unlink(prevfile);
|
||||
unlink_or_warn(prevfile);
|
||||
|
||||
/* Reset inflate/SHA1 if there was an error reading the previous temp
|
||||
file; also rewind to the beginning of the local file. */
|
||||
@@ -238,18 +238,18 @@ static void finish_object_request(struct object_request *obj_req)
|
||||
} else if (obj_req->curl_result != CURLE_OK) {
|
||||
if (stat(obj_req->tmpfile, &st) == 0)
|
||||
if (st.st_size == 0)
|
||||
unlink(obj_req->tmpfile);
|
||||
unlink_or_warn(obj_req->tmpfile);
|
||||
return;
|
||||
}
|
||||
|
||||
git_inflate_end(&obj_req->stream);
|
||||
git_SHA1_Final(obj_req->real_sha1, &obj_req->c);
|
||||
if (obj_req->zret != Z_STREAM_END) {
|
||||
unlink(obj_req->tmpfile);
|
||||
unlink_or_warn(obj_req->tmpfile);
|
||||
return;
|
||||
}
|
||||
if (hashcmp(obj_req->sha1, obj_req->real_sha1)) {
|
||||
unlink(obj_req->tmpfile);
|
||||
unlink_or_warn(obj_req->tmpfile);
|
||||
return;
|
||||
}
|
||||
obj_req->rename =
|
||||
@@ -809,7 +809,7 @@ static void abort_object_request(struct object_request *obj_req)
|
||||
close(obj_req->local);
|
||||
obj_req->local = -1;
|
||||
}
|
||||
unlink(obj_req->tmpfile);
|
||||
unlink_or_warn(obj_req->tmpfile);
|
||||
if (obj_req->slot) {
|
||||
release_active_slot(obj_req->slot);
|
||||
obj_req->slot = NULL;
|
||||
|
||||
@@ -219,7 +219,7 @@ static int ll_ext_merge(const struct ll_merge_driver *fn,
|
||||
close(fd);
|
||||
bad:
|
||||
for (i = 0; i < 3; i++)
|
||||
unlink(temp[i]);
|
||||
unlink_or_warn(temp[i]);
|
||||
strbuf_release(&cmd);
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ static void remove_lock_file(void)
|
||||
lock_file_list->filename[0]) {
|
||||
if (lock_file_list->fd >= 0)
|
||||
close(lock_file_list->fd);
|
||||
unlink(lock_file_list->filename);
|
||||
unlink_or_warn(lock_file_list->filename);
|
||||
}
|
||||
lock_file_list = lock_file_list->next;
|
||||
}
|
||||
@@ -259,7 +259,7 @@ void rollback_lock_file(struct lock_file *lk)
|
||||
if (lk->filename[0]) {
|
||||
if (lk->fd >= 0)
|
||||
close(lk->fd);
|
||||
unlink(lk->filename);
|
||||
unlink_or_warn(lk->filename);
|
||||
}
|
||||
lk->filename[0] = 0;
|
||||
}
|
||||
|
||||
@@ -933,11 +933,12 @@ static int process_renames(struct merge_options *o,
|
||||
ren1_src, ren1_dst, branch1,
|
||||
branch2);
|
||||
update_file(o, 0, ren1->pair->two->sha1, ren1->pair->two->mode, ren1_dst);
|
||||
update_stages(ren1_dst, NULL,
|
||||
branch1 == o->branch1 ?
|
||||
ren1->pair->two : NULL,
|
||||
branch1 == o->branch1 ?
|
||||
NULL : ren1->pair->two, 1);
|
||||
if (!o->call_depth)
|
||||
update_stages(ren1_dst, NULL,
|
||||
branch1 == o->branch1 ?
|
||||
ren1->pair->two : NULL,
|
||||
branch1 == o->branch1 ?
|
||||
NULL : ren1->pair->two, 1);
|
||||
} else if (!sha_eq(dst_other.sha1, null_sha1)) {
|
||||
const char *new_path;
|
||||
clean_merge = 0;
|
||||
|
||||
4
object.c
4
object.c
@@ -45,8 +45,8 @@ int type_from_string(const char *str)
|
||||
|
||||
static unsigned int hash_obj(struct object *obj, unsigned int n)
|
||||
{
|
||||
const void *p = obj->sha1;
|
||||
unsigned int hash = *(const unsigned int *)p;
|
||||
unsigned int hash;
|
||||
memcpy(&hash, obj->sha1, sizeof(unsigned int));
|
||||
return hash % n;
|
||||
}
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@ static void prune_ref(struct ref_to_prune *r)
|
||||
struct ref_lock *lock = lock_ref_sha1(r->name + 5, r->sha1);
|
||||
|
||||
if (lock) {
|
||||
unlink(git_path("%s", r->name));
|
||||
unlink_or_warn(git_path("%s", r->name));
|
||||
unlock_ref(lock);
|
||||
}
|
||||
}
|
||||
|
||||
19
refs.c
19
refs.c
@@ -893,8 +893,10 @@ static struct ref_lock *lock_ref_sha1_basic(const char *ref, const unsigned char
|
||||
* name is a proper prefix of our refname.
|
||||
*/
|
||||
if (missing &&
|
||||
!is_refname_available(ref, NULL, get_packed_refs(), 0))
|
||||
!is_refname_available(ref, NULL, get_packed_refs(), 0)) {
|
||||
last_errno = ENOTDIR;
|
||||
goto error_return;
|
||||
}
|
||||
|
||||
lock->lk = xcalloc(1, sizeof(struct lock_file));
|
||||
|
||||
@@ -1002,12 +1004,10 @@ int delete_ref(const char *refname, const unsigned char *sha1, int delopt)
|
||||
} else {
|
||||
path = git_path("%s", refname);
|
||||
}
|
||||
err = unlink(path);
|
||||
if (err && errno != ENOENT) {
|
||||
err = unlink_or_warn(path);
|
||||
if (err && errno != ENOENT)
|
||||
ret = 1;
|
||||
error("unlink(%s) failed: %s",
|
||||
path, strerror(errno));
|
||||
}
|
||||
|
||||
if (!(delopt & REF_NODEREF))
|
||||
lock->lk->filename[i] = '.';
|
||||
}
|
||||
@@ -1017,10 +1017,7 @@ int delete_ref(const char *refname, const unsigned char *sha1, int delopt)
|
||||
*/
|
||||
ret |= repack_without_ref(refname);
|
||||
|
||||
err = unlink(git_path("logs/%s", lock->ref_name));
|
||||
if (err && errno != ENOENT)
|
||||
warning("unlink(%s) failed: %s",
|
||||
git_path("logs/%s", lock->ref_name), strerror(errno));
|
||||
unlink_or_warn(git_path("logs/%s", lock->ref_name));
|
||||
invalidate_cached_refs();
|
||||
unlock_ref(lock);
|
||||
return ret;
|
||||
@@ -1381,7 +1378,7 @@ int create_symref(const char *ref_target, const char *refs_heads_master,
|
||||
if (adjust_shared_perm(git_HEAD)) {
|
||||
error("Unable to fix permissions on %s", lockpath);
|
||||
error_unlink_return:
|
||||
unlink(lockpath);
|
||||
unlink_or_warn(lockpath);
|
||||
error_free_return:
|
||||
free(git_HEAD);
|
||||
return -1;
|
||||
|
||||
2
rerere.c
2
rerere.c
@@ -173,7 +173,7 @@ static int handle_file(const char *path,
|
||||
git_SHA1_Final(sha1, &ctx);
|
||||
if (hunk != RR_CONTEXT) {
|
||||
if (output)
|
||||
unlink(output);
|
||||
unlink_or_warn(output);
|
||||
return error("Could not parse conflict hunks in %s", path);
|
||||
}
|
||||
if (wrerror)
|
||||
|
||||
@@ -6,6 +6,7 @@ struct send_pack_args {
|
||||
send_mirror:1,
|
||||
force_update:1,
|
||||
use_thin_pack:1,
|
||||
use_ofs_delta:1,
|
||||
dry_run:1;
|
||||
};
|
||||
|
||||
|
||||
@@ -246,7 +246,7 @@ int update_server_info(int force)
|
||||
errs = errs | update_info_packs(force);
|
||||
|
||||
/* remove leftover rev-cache file if there is any */
|
||||
unlink(git_path("info/rev-cache"));
|
||||
unlink_or_warn(git_path("info/rev-cache"));
|
||||
|
||||
return errs;
|
||||
}
|
||||
|
||||
@@ -720,6 +720,8 @@ static int open_packed_git_1(struct packed_git *p)
|
||||
return error("packfile %s index unavailable", p->pack_name);
|
||||
|
||||
p->pack_fd = open(p->pack_name, O_RDONLY);
|
||||
while (p->pack_fd < 0 && errno == EMFILE && unuse_one_window(p, -1))
|
||||
p->pack_fd = open(p->pack_name, O_RDONLY);
|
||||
if (p->pack_fd < 0 || fstat(p->pack_fd, &st))
|
||||
return -1;
|
||||
|
||||
@@ -937,6 +939,8 @@ static void prepare_packed_git_one(char *objdir, int local)
|
||||
sprintf(path, "%s/pack", objdir);
|
||||
len = strlen(path);
|
||||
dir = opendir(path);
|
||||
while (!dir && errno == EMFILE && unuse_one_window(packed_git, -1))
|
||||
dir = opendir(path);
|
||||
if (!dir) {
|
||||
if (errno != ENOENT)
|
||||
error("unable to open object pack directory: %s: %s",
|
||||
@@ -2247,7 +2251,7 @@ int move_temp_to_file(const char *tmpfile, const char *filename)
|
||||
goto out;
|
||||
ret = errno;
|
||||
}
|
||||
unlink(tmpfile);
|
||||
unlink_or_warn(tmpfile);
|
||||
if (ret) {
|
||||
if (ret != EEXIST) {
|
||||
return error("unable to write sha1 filename %s: %s\n", filename, strerror(ret));
|
||||
@@ -2339,6 +2343,8 @@ static int write_loose_object(const unsigned char *sha1, char *hdr, int hdrlen,
|
||||
|
||||
filename = sha1_file_name(sha1);
|
||||
fd = create_tmpfile(tmpfile, sizeof(tmpfile), filename);
|
||||
while (fd < 0 && errno == EMFILE && unuse_one_window(packed_git, -1))
|
||||
fd = create_tmpfile(tmpfile, sizeof(tmpfile), filename);
|
||||
if (fd < 0) {
|
||||
if (errno == EACCES)
|
||||
return error("insufficient permission for adding an object to repository database %s\n", get_object_directory());
|
||||
|
||||
95
t/t3031-merge-criscross.sh
Executable file
95
t/t3031-merge-criscross.sh
Executable file
@@ -0,0 +1,95 @@
|
||||
#!/bin/sh
|
||||
|
||||
test_description='merge-recursive backend test'
|
||||
|
||||
. ./test-lib.sh
|
||||
|
||||
# A <- create some files
|
||||
# / \
|
||||
# B C <- cause rename/delete conflicts between B and C
|
||||
# / \
|
||||
# |\ /|
|
||||
# | D E |
|
||||
# | \ / |
|
||||
# | X |
|
||||
# | / \ |
|
||||
# | / \ |
|
||||
# |/ \|
|
||||
# F G <- merge E into B, D into C
|
||||
# \ /
|
||||
# \ /
|
||||
# \ /
|
||||
# H <- recursive merge crashes
|
||||
#
|
||||
|
||||
# initialize
|
||||
test_expect_success 'setup repo with criss-cross history' '
|
||||
mkdir data &&
|
||||
|
||||
# create a bunch of files
|
||||
n=1 &&
|
||||
while test $n -le 10
|
||||
do
|
||||
echo $n > data/$n &&
|
||||
n=$(($n+1)) ||
|
||||
break
|
||||
done &&
|
||||
|
||||
# check them in
|
||||
git add data &&
|
||||
git commit -m A &&
|
||||
git branch A &&
|
||||
|
||||
# a file in one branch
|
||||
git checkout -b B A &&
|
||||
git rm data/9 &&
|
||||
git add data &&
|
||||
git commit -m B &&
|
||||
|
||||
# with a branch off of it
|
||||
git branch D &&
|
||||
|
||||
# put some commits on D
|
||||
git checkout D &&
|
||||
echo testD > data/testD &&
|
||||
git add data &&
|
||||
git commit -m D &&
|
||||
|
||||
# back up to the top, create another branch and cause
|
||||
# a rename conflict with the file we deleted earlier
|
||||
git checkout -b C A &&
|
||||
git mv data/9 data/new-9 &&
|
||||
git add data &&
|
||||
git commit -m C &&
|
||||
|
||||
# with a branch off of it
|
||||
git branch E &&
|
||||
|
||||
# put a commit on E
|
||||
git checkout E &&
|
||||
echo testE > data/testE &&
|
||||
git add data &&
|
||||
git commit -m E &&
|
||||
|
||||
# now, merge E into B
|
||||
git checkout B &&
|
||||
test_must_fail git merge E &&
|
||||
# force-resolve
|
||||
git add data &&
|
||||
git commit -m F &&
|
||||
git branch F &&
|
||||
|
||||
# and merge D into C
|
||||
git checkout C &&
|
||||
test_must_fail git merge D &&
|
||||
# force-resolve
|
||||
git add data &&
|
||||
git commit -m G &&
|
||||
git branch G
|
||||
'
|
||||
|
||||
test_expect_success 'recursive merge between F and G, causes segfault' '
|
||||
git merge F
|
||||
'
|
||||
|
||||
test_done
|
||||
@@ -165,4 +165,42 @@ test_expect_success FILEMODE 'stage mode but not hunk' '
|
||||
|
||||
# end of tests disabled when filemode is not usable
|
||||
|
||||
test_expect_success 'setup again' '
|
||||
git reset --hard &&
|
||||
test_chmod +x file &&
|
||||
echo content >>file
|
||||
'
|
||||
|
||||
# Write the patch file with a new line at the top and bottom
|
||||
cat >patch <<EOF
|
||||
index 180b47c..b6f2c08 100644
|
||||
--- a/file
|
||||
+++ b/file
|
||||
@@ -1,2 +1,4 @@
|
||||
+firstline
|
||||
baseline
|
||||
content
|
||||
+lastline
|
||||
EOF
|
||||
# Expected output, similar to the patch but w/ diff at the top
|
||||
cat >expected <<EOF
|
||||
diff --git a/file b/file
|
||||
index b6f2c08..61b9053 100755
|
||||
--- a/file
|
||||
+++ b/file
|
||||
@@ -1,2 +1,4 @@
|
||||
+firstline
|
||||
baseline
|
||||
content
|
||||
+lastline
|
||||
EOF
|
||||
# Test splitting the first patch, then adding both
|
||||
test_expect_success 'add first line works' '
|
||||
git commit -am "clear local changes" &&
|
||||
git apply patch &&
|
||||
(echo s; echo y; echo y) | git add -p file &&
|
||||
git diff --cached > diff &&
|
||||
test_cmp expected diff
|
||||
'
|
||||
|
||||
test_done
|
||||
|
||||
@@ -505,4 +505,15 @@ test_expect_success 'format-patch from a subdirectory (3)' '
|
||||
test -f "$basename"
|
||||
'
|
||||
|
||||
test_expect_success 'format-patch --in-reply-to' '
|
||||
git format-patch -1 --stdout --in-reply-to "baz@foo.bar" > patch8 &&
|
||||
grep "^In-Reply-To: <baz@foo.bar>" patch8 &&
|
||||
grep "^References: <baz@foo.bar>" patch8
|
||||
'
|
||||
|
||||
test_expect_success 'format-patch --signoff' '
|
||||
git format-patch -1 --signoff --stdout |
|
||||
grep "^Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>"
|
||||
'
|
||||
|
||||
test_done
|
||||
|
||||
@@ -86,6 +86,13 @@ test_expect_success 'format.numbered && --no-numbered' '
|
||||
|
||||
'
|
||||
|
||||
test_expect_success 'format.numbered && --keep-subject' '
|
||||
|
||||
git format-patch --keep-subject --stdout HEAD^ >patch4a &&
|
||||
grep "^Subject: Third" patch4a
|
||||
|
||||
'
|
||||
|
||||
test_expect_success 'format.numbered = auto' '
|
||||
|
||||
git config format.numbered auto
|
||||
@@ -108,4 +115,10 @@ test_expect_success 'format.numbered = auto && --no-numbered' '
|
||||
|
||||
'
|
||||
|
||||
test_expect_success '--start-number && --numbered' '
|
||||
|
||||
git format-patch --start-number 3 --numbered --stdout HEAD~1 > patch8 &&
|
||||
grep "^Subject: \[PATCH 3/3\]" patch8
|
||||
'
|
||||
|
||||
test_done
|
||||
|
||||
42
t/t4131-apply-fake-ancestor.sh
Executable file
42
t/t4131-apply-fake-ancestor.sh
Executable file
@@ -0,0 +1,42 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2009 Stephen Boyd
|
||||
#
|
||||
|
||||
test_description='git apply --build-fake-ancestor handling.'
|
||||
|
||||
. ./test-lib.sh
|
||||
|
||||
test_expect_success 'setup' '
|
||||
test_commit 1 &&
|
||||
test_commit 2 &&
|
||||
mkdir sub &&
|
||||
test_commit 3 sub/3 &&
|
||||
test_commit 4
|
||||
'
|
||||
|
||||
test_expect_success 'apply --build-fake-ancestor' '
|
||||
git checkout 2 &&
|
||||
echo "A" > 1.t &&
|
||||
git diff > 1.patch &&
|
||||
git reset --hard &&
|
||||
git checkout 1 &&
|
||||
git apply --build-fake-ancestor 1.ancestor 1.patch
|
||||
'
|
||||
|
||||
test_expect_success 'apply --build-fake-ancestor in a subdirectory' '
|
||||
git checkout 3 &&
|
||||
echo "C" > sub/3.t &&
|
||||
git diff > 3.patch &&
|
||||
git reset --hard &&
|
||||
git checkout 4 &&
|
||||
(
|
||||
cd sub &&
|
||||
git apply --build-fake-ancestor 3.ancestor ../3.patch &&
|
||||
test -f 3.ancestor
|
||||
) &&
|
||||
git apply --build-fake-ancestor 3.ancestor 3.patch &&
|
||||
test_cmp sub/3.ancestor 3.ancestor
|
||||
'
|
||||
|
||||
test_done
|
||||
@@ -494,5 +494,15 @@ test_expect_success 'remote prune to cause a dangling symref' '
|
||||
grep "dangling symref" err
|
||||
'
|
||||
|
||||
test_expect_success 'show empty remote' '
|
||||
|
||||
test_create_repo empty &&
|
||||
git clone empty empty-clone &&
|
||||
(
|
||||
cd empty-clone &&
|
||||
git remote show origin
|
||||
)
|
||||
'
|
||||
|
||||
test_done
|
||||
|
||||
|
||||
@@ -54,6 +54,12 @@ deduxit me super semitas jusitiae,
|
||||
EOF
|
||||
printf "propter nomen suum." >> new4.txt
|
||||
|
||||
test_expect_success 'merge with no changes' '
|
||||
cp orig.txt test.txt &&
|
||||
git merge-file test.txt orig.txt orig.txt &&
|
||||
test_cmp test.txt orig.txt
|
||||
'
|
||||
|
||||
cp new1.txt test.txt
|
||||
test_expect_success "merge without conflict" \
|
||||
"git merge-file test.txt orig.txt new2.txt"
|
||||
|
||||
@@ -209,4 +209,36 @@ test_expect_success 'merge-msg test #5-2' '
|
||||
test_cmp expected actual
|
||||
'
|
||||
|
||||
test_expect_success 'merge-msg -F' '
|
||||
|
||||
git config --unset-all merge.log
|
||||
git config --unset-all merge.summary
|
||||
git config merge.summary yes &&
|
||||
|
||||
git checkout master &&
|
||||
setdate &&
|
||||
git fetch . left right &&
|
||||
|
||||
git fmt-merge-msg -F .git/FETCH_HEAD >actual &&
|
||||
test_cmp expected actual
|
||||
'
|
||||
|
||||
test_expect_success 'merge-msg -F in subdirectory' '
|
||||
|
||||
git config --unset-all merge.log
|
||||
git config --unset-all merge.summary
|
||||
git config merge.summary yes &&
|
||||
|
||||
git checkout master &&
|
||||
setdate &&
|
||||
git fetch . left right &&
|
||||
mkdir sub &&
|
||||
cp .git/FETCH_HEAD sub/FETCH_HEAD &&
|
||||
(
|
||||
cd sub &&
|
||||
git fmt-merge-msg -F FETCH_HEAD >../actual
|
||||
) &&
|
||||
test_cmp expected actual
|
||||
'
|
||||
|
||||
test_done
|
||||
|
||||
@@ -16,12 +16,13 @@ test_expect_success setup '
|
||||
echo foo mmap bar_mmap
|
||||
echo foo_mmap bar mmap baz
|
||||
} >file &&
|
||||
echo ww w >w &&
|
||||
echo x x xx x >x &&
|
||||
echo y yy >y &&
|
||||
echo zzz > z &&
|
||||
mkdir t &&
|
||||
echo test >t/t &&
|
||||
git add file x y z t/t &&
|
||||
git add file w x y z t/t &&
|
||||
test_tick &&
|
||||
git commit -m initial
|
||||
'
|
||||
@@ -48,6 +49,12 @@ do
|
||||
diff expected actual
|
||||
'
|
||||
|
||||
test_expect_success "grep -w $L (w)" '
|
||||
: >expected &&
|
||||
! git grep -n -w -e "^w" >actual &&
|
||||
test_cmp expected actual
|
||||
'
|
||||
|
||||
test_expect_success "grep -w $L (x)" '
|
||||
{
|
||||
echo ${HC}x:1:x x xx x
|
||||
|
||||
@@ -534,4 +534,12 @@ test_expect_success 'failing checkout -b should not break working tree' '
|
||||
|
||||
'
|
||||
|
||||
test_expect_success 'switch out of non-branch' '
|
||||
git reset --hard master &&
|
||||
git checkout master^0 &&
|
||||
echo modified >one &&
|
||||
test_must_fail git checkout renamer 2>error.log &&
|
||||
! grep "^Previous HEAD" error.log
|
||||
'
|
||||
|
||||
test_done
|
||||
|
||||
@@ -183,4 +183,14 @@ test_expect_success 'commit message from stdin' '
|
||||
commit_msg_is "Log with foo word"
|
||||
'
|
||||
|
||||
test_expect_success 'commit -F overrides -t' '
|
||||
(
|
||||
cd subdir &&
|
||||
echo "-F log" > f.log &&
|
||||
echo "-t template" > t.template &&
|
||||
git commit --allow-empty -F f.log -t t.template
|
||||
) &&
|
||||
commit_msg_is "-F log"
|
||||
'
|
||||
|
||||
test_done
|
||||
|
||||
@@ -129,4 +129,19 @@ test_expect_success 'blame wholesale copy and more' '
|
||||
|
||||
'
|
||||
|
||||
test_expect_success 'blame path that used to be a directory' '
|
||||
mkdir path &&
|
||||
echo A A A A A >path/file &&
|
||||
echo B B B B B >path/elif &&
|
||||
git add path &&
|
||||
test_tick &&
|
||||
git commit -m "path was a directory" &&
|
||||
rm -fr path &&
|
||||
echo A A A A A >path &&
|
||||
git add path &&
|
||||
test_tick &&
|
||||
git commit -m "path is a regular file" &&
|
||||
git blame HEAD^.. -- path
|
||||
'
|
||||
|
||||
test_done
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#
|
||||
# To enable this hook, rename this file to "pre-commit".
|
||||
|
||||
if git-rev-parse --verify HEAD 2>/dev/null
|
||||
if git-rev-parse --verify HEAD >/dev/null 2>&1
|
||||
then
|
||||
against=HEAD
|
||||
else
|
||||
|
||||
@@ -1069,7 +1069,7 @@ int transport_fetch_refs(struct transport *transport, const struct ref *refs)
|
||||
void transport_unlock_pack(struct transport *transport)
|
||||
{
|
||||
if (transport->pack_lockfile) {
|
||||
unlink(transport->pack_lockfile);
|
||||
unlink_or_warn(transport->pack_lockfile);
|
||||
free(transport->pack_lockfile);
|
||||
transport->pack_lockfile = NULL;
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ static void unlink_entry(struct cache_entry *ce)
|
||||
{
|
||||
if (has_symlink_or_noent_leading_path(ce->name, ce_namelen(ce)))
|
||||
return;
|
||||
if (unlink(ce->name))
|
||||
if (unlink_or_warn(ce->name))
|
||||
return;
|
||||
schedule_dir_for_removal(ce->name, ce_namelen(ce));
|
||||
}
|
||||
|
||||
16
wrapper.c
16
wrapper.c
@@ -289,3 +289,19 @@ int odb_pack_keep(char *name, size_t namesz, unsigned char *sha1)
|
||||
safe_create_leading_directories(name);
|
||||
return open(name, O_RDWR|O_CREAT|O_EXCL, 0600);
|
||||
}
|
||||
|
||||
int unlink_or_warn(const char *file)
|
||||
{
|
||||
int rc = unlink(file);
|
||||
|
||||
if (rc < 0) {
|
||||
int err = errno;
|
||||
if (ENOENT != err) {
|
||||
warning("unable to unlink %s: %s",
|
||||
file, strerror(errno));
|
||||
errno = err;
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
@@ -563,23 +563,22 @@ int xdl_merge(mmfile_t *orig, mmfile_t *mf1, const char *name1,
|
||||
return -1;
|
||||
}
|
||||
status = 0;
|
||||
if (xscr1 || xscr2) {
|
||||
if (!xscr1) {
|
||||
result->ptr = xdl_malloc(mf2->size);
|
||||
memcpy(result->ptr, mf2->ptr, mf2->size);
|
||||
result->size = mf2->size;
|
||||
} else if (!xscr2) {
|
||||
result->ptr = xdl_malloc(mf1->size);
|
||||
memcpy(result->ptr, mf1->ptr, mf1->size);
|
||||
result->size = mf1->size;
|
||||
} else {
|
||||
status = xdl_do_merge(&xe1, xscr1, name1,
|
||||
&xe2, xscr2, name2,
|
||||
flags, xpp, result);
|
||||
}
|
||||
xdl_free_script(xscr1);
|
||||
xdl_free_script(xscr2);
|
||||
if (!xscr1) {
|
||||
result->ptr = xdl_malloc(mf2->size);
|
||||
memcpy(result->ptr, mf2->ptr, mf2->size);
|
||||
result->size = mf2->size;
|
||||
} else if (!xscr2) {
|
||||
result->ptr = xdl_malloc(mf1->size);
|
||||
memcpy(result->ptr, mf1->ptr, mf1->size);
|
||||
result->size = mf1->size;
|
||||
} else {
|
||||
status = xdl_do_merge(&xe1, xscr1, name1,
|
||||
&xe2, xscr2, name2,
|
||||
flags, xpp, result);
|
||||
}
|
||||
xdl_free_script(xscr1);
|
||||
xdl_free_script(xscr2);
|
||||
|
||||
xdl_free_env(&xe1);
|
||||
xdl_free_env(&xe2);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user