From: Junio C Hamano Date: Mon, 11 May 2015 21:23:39 +0000 (-0700) Subject: Merge branch 'nd/multiple-work-trees' X-Git-Tag: v2.5.0-rc0~143 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/68a2e6a2c80303144807c8c91a087427e3c8e727?ds=inline;hp=--cc Merge branch 'nd/multiple-work-trees' A replacement for contrib/workdir/git-new-workdir that does not rely on symbolic links and make sharing of objects and refs safer by making the borrowee and borrowers aware of each other. * nd/multiple-work-trees: (41 commits) prune --worktrees: fix expire vs worktree existence condition t1501: fix test with split index t2026: fix broken &&-chain t2026 needs procondition SANITY git-checkout.txt: a note about multiple checkout support for submodules checkout: add --ignore-other-wortrees checkout: pass whole struct to parse_branchname_arg instead of individual flags git-common-dir: make "modules/" per-working-directory directory checkout: do not fail if target is an empty directory t2025: add a test to make sure grafts is working from a linked checkout checkout: don't require a work tree when checking out into a new one git_path(): keep "info/sparse-checkout" per work-tree count-objects: report unused files in $GIT_DIR/worktrees/... gc: support prune --worktrees gc: factor out gc.pruneexpire parsing code gc: style change -- no SP before closing parenthesis checkout: clean up half-prepared directories in --to mode checkout: reject if the branch is already checked out elsewhere prune: strategies for linked checkouts checkout: support checking out into a new working directory ... --- 68a2e6a2c80303144807c8c91a087427e3c8e727 diff --cc Documentation/config.txt index 2e5ceaf719,2700a1bb83..948b8b0e5c --- a/Documentation/config.txt +++ b/Documentation/config.txt @@@ -1274,8 -1229,15 +1276,15 @@@ gc.pruneExpire: "now" may be used to disable this grace period and always prune unreachable objects immediately. -gc.pruneworktreesexpire:: ++gc.pruneWorktreesExpire:: + When 'git gc' is run, it will call + 'prune --worktrees --expire 3.months.ago'. + Override the grace period with this config variable. The value + "now" may be used to disable the grace period and prune + $GIT_DIR/worktrees immediately. + -gc.reflogexpire:: -gc..reflogexpire:: +gc.reflogExpire:: +gc..reflogExpire:: 'git reflog expire' removes reflog entries older than this time; defaults to 90 days. With "" (e.g. "refs/stash") in the middle the setting applies only to diff --cc builtin/checkout.c index 4aad49aaa1,8b2bf2093b..2f92328db4 --- a/builtin/checkout.c +++ b/builtin/checkout.c @@@ -20,10 -20,11 +20,11 @@@ #include "resolve-undo.h" #include "submodule.h" #include "argv-array.h" + #include "sigchain.h" static const char * const checkout_usage[] = { - N_("git checkout [options] "), - N_("git checkout [options] [] -- ..."), + N_("git checkout [] "), + N_("git checkout [] [] -- ..."), NULL, }; @@@ -1134,7 -1340,11 +1365,11 @@@ int cmd_checkout(int argc, const char * OPT_BOOL(0, "ignore-skip-worktree-bits", &opts.ignore_skipworktree, N_("do not limit pathspecs to sparse entries only")), OPT_HIDDEN_BOOL(0, "guess", &dwim_new_local_branch, - N_("second guess 'git checkout no-such-branch'")), + N_("second guess 'git checkout '")), + OPT_FILENAME(0, "to", &opts.new_worktree, + N_("check a branch out in a separate working directory")), + OPT_BOOL(0, "ignore-other-worktrees", &opts.ignore_other_worktrees, + N_("do not check if another worktree is holding the given ref")), OPT_END(), }; diff --cc cache.h index b34447ffcf,670e8614df..771b775621 --- a/cache.h +++ b/cache.h @@@ -618,17 -620,8 +621,18 @@@ extern int fsync_object_files extern int core_preload_index; extern int core_apply_sparse_checkout; extern int precomposed_unicode; +extern int protect_hfs; +extern int protect_ntfs; + extern int git_db_env, git_index_env, git_graft_env, git_common_dir_env; +/* + * Include broken refs in all ref iterations, which will + * generally choke dangerous operations rather than letting + * them silently proceed without taking the broken ref into + * account. + */ +extern int ref_paranoia; + /* * The character that begins a commented line in user-editable file * that is subject to stripspace. diff --cc refs.c index 47e4e5380a,5ed991bd92..0312f05257 --- a/refs.c +++ b/refs.c @@@ -1643,9 -1618,20 +1649,19 @@@ static const char *resolve_ref_unsafe_1 } } + const char *resolve_ref_unsafe(const char *refname, int resolve_flags, + unsigned char *sha1, int *flags) + { + struct strbuf sb_path = STRBUF_INIT; + const char *ret = resolve_ref_unsafe_1(refname, resolve_flags, + sha1, flags, &sb_path); + strbuf_release(&sb_path); + return ret; + } + char *resolve_refdup(const char *ref, int resolve_flags, unsigned char *sha1, int *flags) { - const char *ret = resolve_ref_unsafe(ref, resolve_flags, sha1, flags); - return ret ? xstrdup(ret) : NULL; + return xstrdup_or_null(resolve_ref_unsafe(ref, resolve_flags, sha1, flags)); } /* The argument to filter_refs */ @@@ -2272,9 -2243,9 +2288,9 @@@ int dwim_log(const char *str, int len, static struct ref_lock *lock_ref_sha1_basic(const char *refname, const unsigned char *old_sha1, const struct string_list *skip, - int flags, int *type_p) + unsigned int flags, int *type_p) { - char *ref_file; + const char *ref_file; const char *orig_refname = refname; struct ref_lock *lock; int last_errno = 0; @@@ -2341,9 -2313,13 +2357,9 @@@ lock->ref_name = xstrdup(refname); lock->orig_ref_name = xstrdup(orig_refname); ref_file = git_path("%s", refname); - if (missing) - lock->force_write = 1; - if ((flags & REF_NODEREF) && (type & REF_ISSYMREF)) - lock->force_write = 1; retry: - switch (safe_create_leading_directories(ref_file)) { + switch (safe_create_leading_directories_const(ref_file)) { case SCLD_OK: break; /* success */ case SCLD_VANISHED: @@@ -2956,37 -3010,16 +2976,38 @@@ int log_ref_setup(const char *refname, return 0; } +static int log_ref_write_fd(int fd, const unsigned char *old_sha1, + const unsigned char *new_sha1, + const char *committer, const char *msg) +{ + int msglen, written; + unsigned maxlen, len; + char *logrec; + + msglen = msg ? strlen(msg) : 0; + maxlen = strlen(committer) + msglen + 100; + logrec = xmalloc(maxlen); + len = sprintf(logrec, "%s %s %s\n", + sha1_to_hex(old_sha1), + sha1_to_hex(new_sha1), + committer); + if (msglen) + len += copy_msg(logrec + len - 1, msg) - 1; + + written = len <= maxlen ? write_in_full(fd, logrec, len) : -1; + free(logrec); + if (written != len) + return -1; + + return 0; +} + - static int log_ref_write(const char *refname, const unsigned char *old_sha1, - const unsigned char *new_sha1, const char *msg) + static int log_ref_write_1(const char *refname, const unsigned char *old_sha1, + const unsigned char *new_sha1, const char *msg, + struct strbuf *sb_log_file) { - int logfd, result, written, oflags = O_APPEND | O_WRONLY; - unsigned maxlen, len; - int msglen; - const char *log_file; - char *logrec; - const char *committer; + int logfd, result, oflags = O_APPEND | O_WRONLY; - char log_file[PATH_MAX]; ++ char *log_file; if (log_all_ref_updates < 0) log_all_ref_updates = !is_bare_repository();