Message ID | pull.673.v2.git.1594329108.gitgitgadget@gmail.com (mailing list archive) |
---|---|
Headers | show |
Series | Remove special casing for PSEUDOREF updates | expand |
"Han-Wen Nienhuys via GitGitGadget" <gitgitgadget@gmail.com> writes: > This gets rid of the special casing code for pseudorefs in refs.c > > This is in preparation for reftable. > > v2 > > * remove special casing of non-HEAD pseudorefs; update t1400 and t1405 > accordingly > * open question: should git-update-ref.txt be updated, when it talks about > logAllRefUpdates? This does make writing ORIG_HEAD and friends a lot more heavyweight that just "write a 40-byte text file on the filesystem to remember it for a short while", and it becomes even so with the whole reflog thing, but I think it is a good longer term direction to go. Others may disagree, though. In any case, if we are changing the behaviour with these patches, we should update the documentation. Thanks.
This gets rid of the special casing code for pseudorefs in refs.c This is in preparation for reftable. v2 * remove special casing of non-HEAD pseudorefs; update t1400 and t1405 accordingly * open question: should git-update-ref.txt be updated, when it talks about logAllRefUpdates? Han-Wen Nienhuys (3): t1400: use git rev-parse for testing PSEUDOREF existence Modify pseudo refs through ref backend storage Make HEAD a PSEUDOREF rather than PER_WORKTREE. refs.c | 127 +++----------------------------------- t/t1400-update-ref.sh | 30 ++++----- t/t1405-main-ref-store.sh | 5 +- 3 files changed, 29 insertions(+), 133 deletions(-) base-commit: 4a0fcf9f760c9774be77f51e1e88a7499b53d2e2 Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-673%2Fhanwen%2Fpseudoref-v2 Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-673/hanwen/pseudoref-v2 Pull-Request: https://github.com/gitgitgadget/git/pull/673 Range-diff vs v1: -: ---------- > 1: 9c3dc4b2cb t1400: use git rev-parse for testing PSEUDOREF existence 1: 6821f57bdf ! 2: 871b411517 Modify pseudo refs through ref backend storage @@ Commit message well. Tooling that works directly on files under .git should be updated to use git commands to read refs instead. - This needs the following fixes + The following behaviors change: - * Only write log for HEAD pseudo ref. Fixes t1400 - 'core.logAllRefUpdates=always creates no reflog for ORIG_HEAD' + * Updates to pseudorefs (eg. ORIG_HEAD) with + core.logAllRefUpdates=always will create reflogs for the pseudoref. - * t1400: change hard coded error messages to check for. - - * don't deref non-HEAD pseudoref symrefs. This fixes t1405. Without - this, a deleting a FOO symref pointing to refs/heads/master will remove - master too. + * non-HEAD pseudoref symrefs are also dereferenced on deletion. Update + t1405 accordingly. Signed-off-by: Han-Wen Nienhuys <hanwen@google.com> @@ refs.c: int refs_update_ref(struct ref_store *refs, const char *msg, if (ret) { const char *str = _("update_ref failed for ref '%s': %s"); - ## refs/files-backend.c ## -@@ refs/files-backend.c: static int files_delete_refs(struct ref_store *ref_store, const char *msg, - - for (i = 0; i < refnames->nr; i++) { - const char *refname = refnames->items[i].string; -- - if (refs_delete_ref(&refs->base, msg, refname, NULL, flags)) - result |= error(_("could not remove reference %s"), refname); - } -@@ refs/files-backend.c: static int lock_ref_for_update(struct files_ref_store *refs, - update->backend_data = lock; + ## t/t1400-update-ref.sh ## +@@ t/t1400-update-ref.sh: test_expect_success 'core.logAllRefUpdates=always creates reflog by default' ' + git reflog exists $outside + ' - if (update->type & REF_ISSYMREF) { -- if (update->flags & REF_NO_DEREF) { -+ if (update->flags & REF_NO_DEREF || -+ (ref_type(update->refname) == REF_TYPE_PSEUDOREF && -+ strcmp(update->refname, "HEAD"))) { - /* - * We won't be reading the referent as part of - * the transaction, so we have to read it here -@@ refs/files-backend.c: static int files_transaction_finish(struct ref_store *ref_store, - struct ref_update *update = transaction->updates[i]; - struct ref_lock *lock = update->backend_data; +-test_expect_success 'core.logAllRefUpdates=always creates no reflog for ORIG_HEAD' ' ++test_expect_success 'core.logAllRefUpdates=always creates reflog for ORIG_HEAD' ' + test_config core.logAllRefUpdates always && + git update-ref ORIG_HEAD $A && +- test_must_fail git reflog exists ORIG_HEAD ++ git reflog exists ORIG_HEAD + ' -- if (update->flags & REF_NEEDS_COMMIT || -- update->flags & REF_LOG_ONLY) { -+ if ((ref_type(lock->ref_name) != REF_TYPE_PSEUDOREF || -+ !strcmp(lock->ref_name, "HEAD")) && -+ (update->flags & REF_NEEDS_COMMIT || -+ update->flags & REF_LOG_ONLY)) { - if (files_log_ref_write(refs, - lock->ref_name, - &lock->old_oid, - - ## t/t1400-update-ref.sh ## + test_expect_success '--no-create-reflog overrides core.logAllRefUpdates=always' ' @@ t/t1400-update-ref.sh: test_expect_success 'git cat-file blob master@{2005-05-26 23:42}:F (expect OTHER test_expect_success 'given old value for missing pseudoref, do not create' ' test_must_fail git update-ref PSEUDOREF $A $B 2>err && - test_path_is_missing .git/PSEUDOREF && + test_must_fail git rev-parse PSEUDOREF && - test_i18ngrep "could not read ref" err + test_i18ngrep "unable to resolve reference" err ' @@ t/t1400-update-ref.sh: test_expect_success 'git cat-file blob master@{2005-05-26 @@ t/t1400-update-ref.sh: test_expect_success 'overwrite pseudoref with correct old value' ' test_expect_success 'do not overwrite pseudoref with wrong old value' ' test_must_fail git update-ref PSEUDOREF $D $E 2>err && - test $C = $(cat .git/PSEUDOREF) && + test $C = $(git rev-parse PSEUDOREF) && - test_i18ngrep "unexpected object ID" err + test_i18ngrep "cannot lock ref.*expected" err ' @@ t/t1400-update-ref.sh: test_expect_success 'overwrite pseudoref with correct old @@ t/t1400-update-ref.sh: test_expect_success 'do not delete pseudoref with wrong old value' ' git update-ref PSEUDOREF $A && test_must_fail git update-ref -d PSEUDOREF $B 2>err && - test $A = $(cat .git/PSEUDOREF) && + test $A = $(git rev-parse PSEUDOREF) && - test_i18ngrep "unexpected object ID" err + test_i18ngrep "cannot lock ref.*expected" err ' test_expect_success 'delete pseudoref with correct old value' ' + + ## t/t1405-main-ref-store.sh ## +@@ t/t1405-main-ref-store.sh: test_expect_success 'create_symref(FOO, refs/heads/master)' ' + test_expect_success 'delete_refs(FOO, refs/tags/new-tag)' ' + git rev-parse FOO -- && + git rev-parse refs/tags/new-tag -- && ++ m=$(git rev-parse master) && + $RUN delete-refs 0 nothing FOO refs/tags/new-tag && + test_must_fail git rev-parse FOO -- && +- test_must_fail git rev-parse refs/tags/new-tag -- ++ test_must_fail git rev-parse refs/tags/new-tag --&& ++ test_must_fail git rev-parse master -- && ++ git update-ref refs/heads/master $m + ' + + test_expect_success 'rename_refs(master, new-master)' ' 2: 470821dc6d = 3: 1c2b9d5f17 Make HEAD a PSEUDOREF rather than PER_WORKTREE.