path: root/t/
AgeCommit message (Collapse)Author
2020-10-05Merge branch 'js/default-branch-name-part-2'Junio C Hamano
Update the tests to drop word 'master' from them. * js/default-branch-name-part-2: t9902: avoid using the branch name `master` tests: avoid variations of the `master` branch name t3200: avoid variations of the `master` branch name fast-export: avoid using unnecessary language in a code comment t/test-terminal: avoid non-inclusive language
2020-09-22Merge branch 'al/ref-filter-merged-and-no-merged'Junio C Hamano
"git for-each-ref" and friends that list refs used to allow only one --merged or --no-merged to filter them; they learned to take combination of both kind of filtering. * al/ref-filter-merged-and-no-merged: Doc: prefer more specific file name ref-filter: make internal reachable-filter API more precise ref-filter: allow merged and no-merged filters Doc: cover multiple contains/no-contains filters t3201: test multiple branch filter combinations
2020-09-21t3200: avoid variations of the `master` branch nameJohannes Schindelin
To avoid branch names with a loaded history, we already started to avoid using the name "master" in a couple instances. The `` script uses variations of this name for branches other than the default one. So let's change those names, as "lowest-hanging fruits" in the effort to use more inclusive naming throughout Git's source code. While at it, make those branch names independent from the default branch name. In this particular instance, this rename requires a couple of non-trivial adjustments, as the aligned output depends on the maximum length of the displayed branches (which we now changed), and also on the alphabetical order (which we now changed, too). Signed-off-by: Johannes Schindelin <> Signed-off-by: Junio C Hamano <>
2020-09-16ref-filter: allow merged and no-merged filtersAaron Lipman
Enable ref-filter to process multiple merged and no-merged filters, and extend functionality to git branch, git tag and git for-each-ref. This provides an easy way to check for branches that are "graduation candidates:" $ git branch --no-merged master --merged next If passed more than one merged (or more than one no-merged) filter, refs must be reachable from any one of the merged commits, and reachable from none of the no-merged commits. Signed-off-by: Aaron Lipman <> Signed-off-by: Junio C Hamano <>
2020-09-08t3200: clean side effect of git checkout --orphanAaron Lipman
The "refuse --edit-description on unborn branch for now" test in t3200 switches to an orphan branch, causing subsequent git commands referencing HEAD to fail. Avoid this side-effect by switching back to master after the test finishes. This has gone undetected, as the next affected test expects failure - but it currently fails for the wrong reason. Verbose output of the next test referencing HEAD, "--merged is incompatible with --no-merged": fatal: malformed object name HEAD Which this commit corrects to: error: option `no-merged' is incompatible with --merged Signed-off-by: Aaron Lipman <> Signed-off-by: Junio C Hamano <>
2020-07-18Merge branch 'dl/branch-cleanup' into masterJunio C Hamano
Last minute fix-up to tests for portability. * dl/branch-cleanup: t3200: don't grep for `strerror()` string
2020-07-18t3200: don't grep for `strerror()` stringMartin Ågren
In 6b7093064a ("t3200: test for specific errors", 2020-06-15), we learned to grep stderr to ensure that the failing `git branch` invocations fail for the right reason. In two of these tests, we grep for "File exists", expecting the string to show up there since config.c calls `error_errno()`, which ends up including `strerror(errno)` in the error message. But as we saw in 4605a73073 ("t1091: don't grep for `strerror()` string", 2020-03-08), there exists at least one implementation where `strerror()` yields a slightly different string than the one we're grepping for. In particular, these tests fail on the NonStop platform. Similar to 4605a73073, grep for the beginning of the string instead to avoid relying on `strerror()` behavior. Reported-by: Randall S. Becker <> Signed-off-by: Martin Ågren <> Signed-off-by: Junio C Hamano <>
2020-07-07Merge branch 'bc/sha-256-part-2'Junio C Hamano
SHA-256 migration work continues. * bc/sha-256-part-2: (44 commits) remote-testgit: adapt for object-format bundle: detect hash algorithm when reading refs t5300: pass --object-format to git index-pack t5704: send object-format capability with SHA-256 t5703: use object-format serve option t5702: offer an object-format capability in the test t/helper: initialize the repository for test-sha1-array remote-curl: avoid truncating refs with ls-remote t1050: pass algorithm to index-pack when outside repo builtin/index-pack: add option to specify hash algorithm remote-curl: detect algorithm for dumb HTTP by size builtin/ls-remote: initialize repository based on fetch t5500: make hash independent serve: advertise object-format capability for protocol v2 connect: parse v2 refs with correct hash algorithm connect: pass full packet reader when parsing v2 refs Documentation/technical: document object-format for protocol v2 t1302: expect repo format version 1 for SHA-256 builtin/show-index: provide options to determine hash algo t5302: modernize test formatting ...
2020-06-17t3200: test for specific errorsDenton Liu
In the "--set-upstream-to" and "--unset-upstream" tests, specific error conditions are being tested. However, there is no way of ensuring that a test case is failing because of some specific error. Check stderr of failing commands to ensure that they are failing in the expected way. Signed-off-by: Denton Liu <> Signed-off-by: Junio C Hamano <>
2020-06-17t3200: rename "expected" to "expect"Denton Liu
Clean up style of test by changing some filenames from "expected" to "expect", which follows typical test convention. Also, change a space-indent into a tab-indent. Signed-off-by: Denton Liu <> Signed-off-by: Junio C Hamano <>
2020-05-27t3200: mark assertion with SHA1 prerequisitebrian m. carlson
One of the test assertions in this test checks that git branch -m works even without a .git/config file. However, if the repository requires configuration extensions, such as because it uses a non-SHA-1 algorithm, this assertion will fail. Mark the assertion as requiring SHA-1. Signed-off-by: brian m. carlson <> Signed-off-by: Junio C Hamano <>
2019-07-09Merge branch 'nb/branch-show-other-worktrees-head'Junio C Hamano
"git branch --list" learned to show branches that are checked out in other worktrees connected to the same repository prefixed with '+', similar to the way the currently checked out branch is shown with '*' in front. * nb/branch-show-other-worktrees-head: branch: add worktree info on verbose output branch: update output to include worktree info ref-filter: add worktreepath atom
2019-05-19Merge branch 'dl/branch-from-3dot-merge-base'Junio C Hamano
"git branch new A...B" and "git checkout -b new A...B" have been taught that in their contexts, the notation A...B means "the merge base between these two commits", just like "git checkout A...B" detaches HEAD at that commit. * dl/branch-from-3dot-merge-base: branch: make create_branch accept a merge base rev t2018: cleanup in current test
2019-05-07branch: update output to include worktree infoNickolai Belakovski
The output of git branch is modified to mark branches checked out in a linked worktree with a "+" and color them in cyan (in contrast to the current branch, which will still be denoted with a "*" and colored in green) This is meant to communicate to the user that the branches that are marked or colored will behave differently from other branches if the user attempts to check them out or delete them, since branches checked out in another worktree cannot be checked out or deleted. Signed-off-by: Nickolai Belakovski <> Signed-off-by: Junio C Hamano <>
2019-05-07branch: make create_branch accept a merge base revDenton Liu
When we ran something like $ git checkout -b test master... it would fail with the message fatal: Not a valid object name: 'master...'. This was caused by the call to `create_branch` where `start_name` is expected to be a valid rev. However, git-checkout allows the branch to be a valid _merge base_ rev (i.e. with a "...") so it was possible for an invalid rev to be passed in. Make `create_branch` accept a merge base rev so that this case does not error out. As a side-effect, teach git-branch how to handle merge base revs as well. Helped-by: Junio C Hamano <> Signed-off-by: Denton Liu <> Signed-off-by: Junio C Hamano <>
2019-04-21worktree: update is_bare heuristicsJonathan Tan
When "git branch -D <name>" is run, Git usually first checks if that branch is currently checked out. But this check is not performed if the Git directory of that repository is not at "<repo>/.git", which is the case if that repository is a submodule that has its Git directory stored as "super/.git/modules/<repo>", for example. This results in the branch being deleted even though it is checked out. This is because get_main_worktree() in worktree.c sets is_bare on a worktree only using the heuristic that a repo is bare if the worktree's path does not end in "/.git", and not bare otherwise. This is_bare code was introduced in 92718b7438 ("worktree: add details to the worktree struct", 2015-10-08), following a pre-core.bare heuristic. This patch does 2 things: - Teach get_main_worktree() to use is_bare_repository() instead, introduced in 7d1864ce67 ("Introduce is_bare_repository() and core.bare configuration variable", 2007-01-07) and updated in e90fdc39b6 ("Clean up work-tree handling", 2007-08-01). This solves the "git branch -D <name>" problem described above. However... - If a repository has core.bare=1 but the "git" command is being run from one of its secondary worktrees, is_bare_repository() returns false (which is fine, since there is a worktree available). However, treating the main worktree as non-bare when it is bare causes issues: for example, failure to delete a branch from a secondary worktree that is referred to by a main worktree's HEAD, even if that main worktree is bare. In order to avoid that, also check core.bare when setting is_bare. If core.bare=1, trust it, and otherwise, use is_bare_repository(). Signed-off-by: Jonathan Tan <> Signed-off-by: Junio C Hamano <>
2018-10-06t/*: fix ordering of expected/observed argumentsMatthew DeVore
Fix various places where the ordering was obviously wrong, meaning it was easy to find with grep. Signed-off-by: Matthew DeVore <> Signed-off-by: Junio C Hamano <>
2018-08-16branch: support configuring --sort via .gitconfigSamuel Maftoul
Add support for configuring default sort ordering for git branches. Command line option will override this configured value, using the exact same syntax. Signed-off-by: Samuel Maftoul <> Signed-off-by: Junio C Hamano <>
2018-06-22t: switch "branch -l" to "branch --create-reflog"Jeff King
In preparation for deprecating "-l", let's make sure we're using the recommended option ourselves. This patch just mechanically converts "branch -l" to "branch --create-reflog". Note that with the exception of the actual "--create-reflog" test, we could actually remove "-l" entirely from most of these callers. That's because these days core.logallrefupdates defaults to true in a non-bare repository. I've left them in place, though, since they serve to document the expectation of the test, even if they are technically noops. Signed-off-by: Jeff King <> Signed-off-by: Junio C Hamano <>
2018-06-22t3200: unset core.logallrefupdates when testing reflog creationJeff King
This test checks that the "-l" option creates a reflog. But in fact we'd create one even without it, since the default in a non-bare repository is to do so. Let's unset the config so we can be sure our "-l" option is kicking in. Note that we can't do this with test_config, since that would leave the variable unset after our test finishes, confusing downstream tests (the helper is not not smart enough to restore the previous value, and just always runs test_unconfig). Signed-off-by: Jeff King <> Signed-off-by: Junio C Hamano <>
2018-06-18Merge branch 'ks/branch-set-upstream'Junio C Hamano
A test title has been reworded to clarify it. * ks/branch-set-upstream: t3200: clarify description of --set-upstream test
2018-06-18t3200: clarify description of --set-upstream testKaartic Sivaraam
Support for the --set-upstream option was removed in 52668846ea (builtin/branch: stop supporting the "--set-upstream" option, 2017-08-17). The change did not completely remove the command due to an issue noted in the commit's log message. So, a test was added to ensure that a command which uses the '--set-upstream' option fails instead of silently acting as an alias for the '--set-upstream-to' option due to option parsing features. To avoid confusion, clarify that the option is disabled intentionally in the corresponding test description. The test is expected to be around as long as we intentionally fail on seeing the '--set-upstream' option which in turn we expect to do for a period of time after which we can be sure that existing users of '--set-upstream' are aware that the option is no longer supported. Signed-off-by: Kaartic Sivaraam <> Signed-off-by: Junio C Hamano <>
2018-06-01Merge branch 'cc/tests-without-assuming-ref-files-backend'Junio C Hamano
Quite a many tests assumed that newly created refs are made as loose refs using the files backend, which have been updated to use proper plumbing like rev-parse and update-ref, to avoid breakage once we start using different ref backends. * cc/tests-without-assuming-ref-files-backend: t990X: use '.git/objects' as 'deep inside .git' path t: make many tests depend less on the refs being files
2018-05-23t: make many tests depend less on the refs being filesDavid Turner
Many tests are very focused on the file system representation of the loose and packed refs code. As there are plans to implement other ref storage systems, let's migrate these tests to a form that test the intent of the refs storage system instead of it internals. This will make clear to readers that these tests do not depend on which ref backend is used. The internals of the loose refs backend are still tested in, whereas the tests changed in this patch focus on testing other aspects. This patch just takes care of many low hanging fruits. It does not try to completely solves the issue. Helped-by: Stefan Beller <> Helped-by: Johannes Schindelin <> Signed-off-by: David Turner <> Signed-off-by: Christian Couder <> Signed-off-by: Junio C Hamano <>
2018-05-14t: switch $_z40 to $ZERO_OIDbrian m. carlson
Switch all uses of $_z40 to $ZERO_OID so that they work correctly with larger hashes. This commit was created by using the following sed command to modify all files in the t directory except t/ sed -i 's/\$_z40/$ZERO_OID/g' Signed-off-by: brian m. carlson <> Signed-off-by: Junio C Hamano <>
2018-04-05t3200: verify "branch --list" sanity when rebasing from detached HEADEric Sunshine
"git branch --list" shows an in-progress rebase as: * (no branch, rebasing <branch>) master ... However, if the rebase is started from a detached HEAD, then there is no <branch>, and it would attempt to print a NULL pointer. The previous commit fixed this problem, so add a test to verify that the output is sane in this situation. Signed-off-by: Eric Sunshine <> Signed-off-by: Kaartic Sivaraam <> Signed-off-by: Junio C Hamano <>
2018-03-21Merge branch 'ks/t3200-typofix'Junio C Hamano
Test typofix. * ks/t3200-typofix: t/t3200: fix a typo in a test description
2018-03-15t/t3200: fix a typo in a test descriptionKaartic Sivaraam
Signed-off-by: Kaartic Sivaraam <> Signed-off-by: Junio C Hamano <>
2017-10-07refs_resolve_ref_unsafe: handle d/f conflicts for writesJeff King
If our call to refs_read_raw_ref() fails, we check errno to see if the ref is simply missing, or if we encountered a more serious error. If it's just missing, then in "write" mode (i.e., when RESOLVE_REFS_READING is not set), this is perfectly fine. However, checking for ENOENT isn't sufficient to catch all missing-ref cases. In the filesystem backend, we may also see EISDIR when we try to resolve "a" and "a/b" exists. Likewise, we may see ENOTDIR if we try to resolve "a/b" and "a" exists. In both of those cases, we know that our resolved ref doesn't exist, but we return an error (rather than reporting the refname and returning a null sha1). This has been broken for a long time, but nobody really noticed because the next step after resolving without the READING flag is usually to lock the ref and write it. But in both of those cases, the write will fail with the same errno due to the directory/file conflict. There are two cases where we can notice this, though: 1. If we try to write "a" and there's a leftover directory already at "a", even though there is no ref "a/b". The actual write is smart enough to move the empty "a" out of the way. This is reasonably rare, if only because the writing code has to do an independent resolution before trying its write (because the actual update_ref() code handles this case fine). The notes-merge code does this, and before the fix in the prior commit t3308 erroneously expected this case to fail. 2. When resolving symbolic refs, we typically do not use the READING flag because we want to resolve even symrefs that point to unborn refs. Even if those unborn refs could not actually be written because of d/f conflicts with existing refs. You can see this by asking "git symbolic-ref" to report the target of a symref pointing past a d/f conflict. We can fix the problem by recognizing the other "missing" errnos and treating them like ENOENT. This should be safe to do even for callers who are then going to actually write the ref, because the actual writing process will fail if the d/f conflict is a real one (and t1404 checks these cases). Arguably this should be the responsibility of the files-backend to normalize all "missing ref" errors into ENOENT (since something like EISDIR may not be meaningful at all to a database backend). However other callers of refs_read_raw_ref() may actually care about the distinction; putting this into resolve_ref() is the minimal fix for now. The new tests in t1401 use git-symbolic-ref, which is the most direct way to check the resolution by itself. Interestingly we actually had a test that setup this case already, but we only used it to verify that the funny state could be overwritten, not that it could be resolved. We also add a new test in t3200, as "branch -m" was the original motivation for looking into this. What happens is this: 0. HEAD is pointing to branch "a" 1. The user asks to rename "a" to "a/b". 2. We create "a/b" and delete "a". 3. We then try to update any worktree HEADs that point to the renamed ref (including the main repo HEAD). To do that, we have to resolve each HEAD. But now our HEAD is pointing at "a", and we get EISDIR due to the loose "a/b". As a result, we think there is no HEAD, and we do not update it. It now points to the bogus "a". Interestingly this case used to work, but only accidentally. Before 31824d180d (branch: fix branch renaming not updating HEADs correctly, 2017-08-24), we'd update any HEAD which we couldn't resolve. That was wrong, but it papered over the fact that we were incorrectly failing to resolve HEAD. So while the bug demonstrated by the git-symbolic-ref is quite old, the regression to "branch -m" is recent. Signed-off-by: Jeff King <> Signed-off-by: Junio C Hamano <>
2017-10-03Merge branch 'sd/branch-copy'Junio C Hamano
"git branch" learned "-c/-C" to create a new branch by copying an existing one. * sd/branch-copy: branch: fix "copy" to never touch HEAD branch: add a --copy (-c) option to go with --move (-m) branch: add test for -m renaming multiple config sections config: create a function to format section headers
2017-09-23branch: fix "copy" to never touch HEADJunio C Hamano
When creating a new branch B by copying the branch A that happens to be the current branch, it also updates HEAD to point at the new branch. It probably was made this way because "git branch -c A B" piggybacked its implementation on "git branch -m A B", This does not match the usual expectation. If I were sitting on a blue chair, and somebody comes and repaints it to red, I would accept ending up sitting on a chair that is now red (I am also OK to stand, instead, as there no longer is my favourite blue chair). But if somebody creates a new red chair, modelling it after the blue chair I am sitting on, I do not expect to be booted off of the blue chair and ending up on sitting on the new red one. Let's fix this before it hits 'next'. Those who want to create a new branch and switch to it can do "git checkout B" after doing a "git branch -c B", and if that operation is so useful and deserves a short-hand way to do so, perhaps extend "git checkout -b B" to copy configurations while creating the new branch B. Signed-off-by: Junio C Hamano <>
2017-09-10Merge branch 'nd/worktree-kill-parse-ref'Junio C Hamano
"git branch -M a b" while on a branch that is completely unrelated to either branch a or branch b misbehaved when multiple worktree was in use. This has been fixed. * nd/worktree-kill-parse-ref: branch: fix branch renaming not updating HEADs correctly
2017-08-24branch: fix branch renaming not updating HEADs correctlyNguyễn Thái Ngọc Duy
There are two bugs that sort of work together and cause problems. Let's start with one in replace_each_worktree_head_symref. Before fa099d2322 (worktree.c: kill parse_ref() in favor of refs_resolve_ref_unsafe() - 2017-04-24), this code looks like this: if (strcmp(oldref, worktrees[i]->head_ref)) continue; set_worktree_head_symref(...); After fa099d2322, it is possible that head_ref can be NULL. However, the updated code takes the wrong exit. In the error case (NULL head_ref), we should "continue;" to the next worktree. The updated code makes us _skip_ "continue;" and update HEAD anyway. The NULL head_ref is triggered by the second bug in add_head_info (in the same commit). With the flag RESOLVE_REF_READING, resolve_ref_unsafe() will abort if it cannot resolve the target ref. For orphan checkouts, HEAD always points to an unborned branch, resolving target ref will always fail. Now we have NULL head_ref. Now we always update HEAD. Correct the logic in replace_ function so that we don't accidentally update HEAD on error. As it turns out, correcting the logic bug above breaks branch renaming completely, thanks to the second bug. "git branch -[Mm]" does two steps (on a normal checkout, no orphan!): - rename the branch on disk (e.g. refs/heads/abc to refs/heads/def) - update HEAD if it points to the branch being renamed. At the second step, since the branch pointed to by HEAD (e.g. "abc") no longer exists on disk, we run into a temporary orphan checkout situation that has been just corrected to _not_ update HEAD. But we need to update HEAD since it's not actually an orphan checkout. We need to update HEAD to move out of that orphan state. Correct add_head_info(), remove RESOLVE_REF_READING flag. With the flag gone, we should always return good "head_ref" in orphan checkouts (either temporary or permanent). With good head_ref, things start to work again. Noticed-by: Nish Aravamudan <> Signed-off-by: Nguyễn Thái Ngọc Duy <> Signed-off-by: Junio C Hamano <>
2017-08-17builtin/branch: stop supporting the "--set-upstream" optionKaartic Sivaraam
The '--set-upstream' option of branch was deprecated in b347d06b ("branch: deprecate --set-upstream and show help if we detect possible mistaken use", 2012-08-30) and has been planned for removal ever since. In order to prevent "--set-upstream" on a command line from being taken as an abbreviated form of "--set-upstream-to", explicitly catch "--set-upstream" option and die, instead of just removing it from the list of options. Before this change, an attempt to use "--set-upstream" resulted in: $ git branch * master $ git branch --set-upstream origin/master The --set-upstream flag is deprecated and will be removed. Consider using --track or --set-upstream-to Branch origin/master set up to track local branch master. $ echo $? 0 $ git branch * master origin/master With this change, the behaviour becomes like this: $ git branch * master $ git branch --set-upstream origin/master fatal: the '--set-upstream' option is no longer supported. Please use '--track' or '--set-upstream-to' instead. $ echo $? 128 $ git branch * master Signed-off-by: Kaartic Sivaraam <> Signed-off-by: Junio C Hamano <>
2017-08-17t3200: cleanup cruft of a testKaartic Sivaraam
Avoiding the clean up step of tests may help in some cases but in other cases they cause the other unrelated tests to fail for unobvious reasons. It's better to cleanup a few things to keep other tests from failing as a result of it. So, cleanup a cruft left behind by an old test in order for the changes that are to be introduced to be independent of it. Signed-off-by: Kaartic Sivaraam <> Signed-off-by: Junio C Hamano <>
2017-07-09reflog-walk: stop using fake parentsJeff King
The reflog-walk system works by putting a ref's tip into the pending queue, and then "traversing" the reflog by pretending that the parent of each commit is the previous reflog entry. This causes a number of user-visible oddities, as documented in t1414 (and the commit message which introduced it). We can fix all of them in one go by replacing the fake-reflog system with a much simpler one: just keeping a list of reflogs to show, and walking through them entry by entry. The implementation is fairly straight-forward, but there are a few items to note: 1. We obviously must skip calling add_parents_to_list() when we are traversing reflogs, since we do not want to walk the original parents at all. As a result, we must call try_to_simplify_commit() ourselves. There are other parts of add_parents_to_list() we skip, as well, but none of them should matter for a reflog traversal: - We do not allow UNINTERESTING commits, nor symmetric ranges (and we bail when these are used with "-g"). - Using --source makes no sense, since we aren't traversing. The reflog selector shows the same information with more detail. - Using --first-parent is still sensible, since you may want to see the first-parent diff for each entry. But since we're not traversing, we don't need to cull the parent list here. 2. Since we now just walk the reflog entries themselves, rather than starting with the ref tip, we now look at the "new" field of each entry rather than the "old" (i.e., we are showing entries, not faking parents). This removes all of the tricky logic around skipping past root commits. But note that we have no way to show an entry with the null sha1 in its "new" field (because such a commit obviously does not exist). Normally this would not happen, since we delete reflogs along with refs, but there is one special case. When we rename the currently checked out branch, we write two reflog entries into the HEAD log: one where the commit goes away, and another where it comes back. Prior to this commit, we show both entries with identical reflog messages. After this commit, we show only the "comes back" entry. See the update in t3200 which demonstrates this. Arguably either is fine, as the whole double-entry thing is a bit hacky in the first place. And until a recent fix, we truncated the traversal in such a case anyway, which was _definitely_ wrong. 3. We show individual reflogs in order, but choose which reflog to show at each stage based on which has the most recent timestamp. This interleaves the output from multiple reflogs based on date order, which is probably what you'd want with limiting like "-n 30". Note that the implementation aims for simplicity. It does a linear walk over the reflog queue for each commit it pulls, which may perform badly if you interleave an enormous number of reflogs. That seems like an unlikely use case; if we did want to handle it, we could probably keep a priority queue of reflogs, ordered by the timestamp of their current tip entry. Signed-off-by: Jeff King <> Signed-off-by: Junio C Hamano <>
2017-07-05reflog-walk: skip over double-null oid due to HEAD renameJeff King
Since 39ee4c6c2f (branch: record creation of renamed branch in HEAD's log, 2017-02-20), a rename on the currently checked out branch will create two entries in the HEAD reflog: one where the branch goes away (switching to the null oid), and one where it comes back (switching away from the null oid). This confuses the reflog-walk code. When walking backwards, it first sees the null oid in the "old" field of the second entry. Thanks to the "root commit" logic added by 71abeb753f (reflog: continue walking the reflog past root commits, 2016-06-03), we keep looking for the next entry by scanning the "new" field from the previous entry. But that field is also null! We need to go just a tiny bit further, and look at its "old" field. But with the current code, we decide the reflog has nothing else to show and just give up. To the user this looks like the reflog was truncated by the rename operation, when in fact those entries are still there. This patch does the absolute minimal fix, which is to look back that one extra level and keep traversing. The resulting behavior may not be the _best_ thing to do in the long run (for example, we show both reflog entries each with the same commit id), but it's a simple way to fix the problem without risking further regressions. Signed-off-by: Jeff King <> Signed-off-by: Junio C Hamano <>
2017-06-19branch: add a --copy (-c) option to go with --move (-m)Sahil Dua
Add the ability to --copy a branch and its reflog and configuration, this uses the same underlying machinery as the --move (-m) option except the reflog and configuration is copied instead of being moved. This is useful for e.g. copying a topic branch to a new version, e.g. work to work-2 after submitting the work topic to the list, while preserving all the tracking info and other configuration that goes with the branch, and unlike --move keeping the other already-submitted branch around for reference. Like --move, when the source branch is the currently checked out branch the HEAD is moved to the destination branch. In the case of --move we don't really have a choice (other than remaining on a detached HEAD) and in order to keep the functionality consistent, we are doing it in similar way for --copy too. The most common usage of this feature is expected to be moving to a new topic branch which is a copy of the current one, in that case moving to the target branch is what the user wants, and doesn't unexpectedly behave differently than --move would. One outstanding caveat of this implementation is that: git checkout maint && git checkout master && git branch -c topic && git checkout - Will check out 'maint' instead of 'master'. This is because the @{-N} feature (or its -1 shorthand "-") relies on HEAD reflogs created by the checkout command, so in this case we'll checkout maint instead of master, as the user might expect. What to do about that is left to a future change. Helped-by: Ævar Arnfjörð Bjarmason <> Signed-off-by: Ævar Arnfjörð Bjarmason <> Signed-off-by: Sahil Dua <> Signed-off-by: Junio C Hamano <>
2017-06-19branch: add test for -m renaming multiple config sectionsÆvar Arnfjörð Bjarmason
Add a test for how 'git branch -m' handles the renaming of multiple config sections existing for one branch. The config format we use is hybrid machine/human editable, and we do our best to preserve the likes of comments and formatting when editing the file with git-config. This adds a test for the currently expected semantics in the face of some rather obscure edge cases which are unlikely to occur in practice. Helped-by: Sahil Dua <> Signed-off-by: Ævar Arnfjörð Bjarmason <> Signed-off-by: Sahil Dua <> Signed-off-by: Junio C Hamano <>
2017-06-13t3200: add test for single parameter passed to -m optionSahil Dua
Add a test for the case when only one parameter is passed to '-m' (move/rename) option. For example - if 'git branch -m bbb' is run while checked out on aaa branch, it should rename the currently checked out branch to bbb. There was no test for this particular case with only one parameter for -m option. However, there's one similar test case for -M option. Add test for making sure HEAD points to the bbb (new branch name). Also add a test for making sure the reflog that is moved to 'bbb' retains entries created for the currently checked out branch. Note that since the topmost entry on reflog for bbb will be about branch creation, we compare bbb@{1} (instead of bbb@{0}) with aaa@{0} to make sure the reflog for bbb retains entries from aaa. Signed-off-by: Sahil Dua <> Signed-off-by: Junio C Hamano <>
2017-06-05Merge branch 'sd/t3200-typofix' into maintJunio C Hamano
Test fix. * sd/t3200-typofix: branch test: fix invalid config key access
2017-06-04Merge branch 'sd/t3200-typofix'Junio C Hamano
Test fix. * sd/t3200-typofix: branch test: fix invalid config key access
2017-05-29branch test: fix invalid config key accessSahil Dua
Fixes the test by changing "branch.s/s/dummy" to "branch.s/s.dummy" which is the right way of accessing config key "branch.s/s.dummy". Purpose of this test is to confirm that this key doesn't exist after the branch "s/s" has been renamed to "s". Earlier it was trying to access invalid config key and hence was getting an error. However, this wasn't caught because we were expecting the command to fail for other reason as mentioned above. Signed-off-by: Sahil Dua <> Signed-off-by: Junio C Hamano <>
2017-04-11Merge branch 'ab/ref-filter-no-contains'Junio C Hamano
"git tag/branch/for-each-ref" family of commands long allowed to filter the refs by "--contains X" (show only the refs that are descendants of X), "--merged X" (show only the refs that are ancestors of X), "--no-merged X" (show only the refs that are not ancestors of X). One curious omission, "--no-contains X" (show only the refs that are not descendants of X) has been added to them. * ab/ref-filter-no-contains: tag: add tests for --with and --without ref-filter: reflow recently changed branch/tag/for-each-ref docs ref-filter: add --no-contains option to tag/branch/for-each-ref tag: change --point-at to default to HEAD tag: implicitly supply --list given another list-like option tag: change misleading --list <pattern> documentation parse-options: add OPT_NONEG to the "contains" option tag: add more incompatibles mode tests for-each-ref: partly change <object> to <commit> in help tag tests: fix a typo in a test description tag: remove a TODO item from the test suite ref-filter: add test for --contains on a non-commit ref-filter: make combining --merged & --no-merged an error tag doc: reword --[no-]merged to talk about commits, not tips tag doc: split up the --[no-]merged documentation tag doc: move the description of --[no-]merged earlier
2017-03-21ref-filter: make combining --merged & --no-merged an errorÆvar Arnfjörð Bjarmason
Change the behavior of specifying --merged & --no-merged to be an error, instead of silently picking the option that was provided last. Subsequent changes of mine add a --no-contains option in addition to the existing --contains. Providing both of those isn't an error, and has actual meaning. Making its cousins have different behavior in this regard would be confusing to the user, especially since we'd be silently disregarding some of their command-line input. Signed-off-by: Ævar Arnfjörð Bjarmason <> Signed-off-by: Junio C Hamano <>
2017-03-14Merge branch 'kn/ref-filter-branch-list'Junio C Hamano
"git branch --list" takes the "--abbrev" and "--no-abbrev" options to control the output of the object name in its "-v"(erbose) output, but a recent update started ignoring them; this fixes it before the breakage reaches to any released version. * kn/ref-filter-branch-list: branch: honor --abbrev/--no-abbrev in --list mode
2017-03-10branch: honor --abbrev/--no-abbrev in --list modeJunio C Hamano
When the "branch --list" command was converted to use the --format facility from the ref-filter API, we forgot to honor the --abbrev setting in the default output format and instead used a hardcoded "7". Signed-off-by: Junio C Hamano <>
2017-02-21branch: record creation of renamed branch in HEAD's logKyle Meyer
Renaming the current branch adds an event to the current branch's log and to HEAD's log. However, the logged entries differ. The entry in the branch's log represents the entire renaming operation (the old and new hash are identical), whereas the entry in HEAD's log represents the deletion only (the new sha1 is null). Extend replace_each_worktree_head_symref(), whose only caller is branch_rename(), to take a reflog message argument. This allows the creation of the new ref to be recorded in HEAD's log. As a result, the renaming event is represented by two entries (a deletion and a creation entry) in HEAD's log. It's a bit unfortunate that the branch's log and HEAD's log now represent the renaming event in different ways. Given that the renaming operation is not atomic, the two-entry form is a more accurate representation of the operation and is more useful for debugging purposes if a failure occurs between the deletion and creation events. It would make sense to move the branch's log to the two-entry form, but this would involve changes to how the rename is carried out and to how the update flags and reflogs are processed for deletions, so it may not be worth the effort. Based-on-patch-by: Jeff King <> Signed-off-by: Kyle Meyer <> Signed-off-by: Junio C Hamano <>
2017-02-21rename_ref: replace empty message in HEAD's logKyle Meyer
When the current branch is renamed, the deletion of the old ref is recorded in HEAD's log with an empty message. Now that delete_ref() accepts a reflog message, provide a more descriptive message by passing along the log message that is given to rename_ref(). The next step will be to extend HEAD's log to also include the second part of the rename, the creation of the new branch. Helped-by: Jeff King <> Signed-off-by: Kyle Meyer <> Signed-off-by: Junio C Hamano <>
2016-07-25Merge branch 'mh/split-under-lock'Junio C Hamano
Further preparatory work on the refs API before the pluggable backend series can land. * mh/split-under-lock: (33 commits) lock_ref_sha1_basic(): only handle REF_NODEREF mode commit_ref_update(): remove the flags parameter lock_ref_for_update(): don't resolve symrefs lock_ref_for_update(): don't re-read non-symbolic references refs: resolve symbolic refs first ref_transaction_update(): check refname_is_safe() at a minimum unlock_ref(): move definition higher in the file lock_ref_for_update(): new function add_update(): initialize the whole ref_update verify_refname_available(): adjust constness in declaration refs: don't dereference on rename refs: allow log-only updates delete_branches(): use resolve_refdup() ref_transaction_commit(): correctly report close_ref() failure ref_transaction_create(): disallow recursive pruning refs: make error messages more consistent lock_ref_sha1_basic(): remove unneeded local variable read_raw_ref(): move docstring to header file read_raw_ref(): improve docstring read_raw_ref(): rename symref argument to referent ...