Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
6b79aee
backfill: reject rev-list arguments that do not make sense
newren Apr 15, 2026
ef6d3c9
backfill: document acceptance of revision-range in more standard manner
newren Apr 15, 2026
a1ad4a0
backfill: default to grabbing edge blobs too
newren Apr 15, 2026
7002d6c
t7004: drop hardcoded tag count for state verification
SiddharthShrimali Apr 21, 2026
e325325
t7004: dynamically grab expected state in tests
SiddharthShrimali Apr 21, 2026
ef85286
t7004: avoid subshells to capture git exit codes
SiddharthShrimali Apr 21, 2026
7584d10
Fix docs for format.commitListFormat
Mroik Apr 22, 2026
b2eec66
merge-ort: handle cached rename & trivial resolution interaction better
newren Apr 20, 2026
9ff4b5a
grep: fix --column --only-match for 2nd and later matches
rscharfe Apr 24, 2026
13817db
stash: add --label-ours, --label-theirs, --label-base for apply
HaraldNordgren Apr 28, 2026
93177db
sequencer: allow create_autostash to run silently
HaraldNordgren Apr 28, 2026
e1c8b2d
sequencer: teach autostash apply to take optional conflict marker labels
HaraldNordgren Apr 28, 2026
26e4e50
checkout: rollback lock on early returns in merge_working_tree
HaraldNordgren Apr 28, 2026
c07039e
checkout -m: autostash when switching branches
HaraldNordgren Apr 28, 2026
8547908
worktree: rename get_worktree_from_repository()
phillipwood May 1, 2026
27caa6b
Merge branch 'en/backfill-fixes-and-edges'
gitster May 17, 2026
f7ae594
Merge branch 'ss/t7004-unhide-git-failures'
gitster May 17, 2026
3cfbb7b
Merge branch 'en/ort-cached-rename-with-trivial-resolution'
gitster May 17, 2026
c26c58d
Merge branch 'mf/format-patch-cover-letter-format-docfix'
gitster May 17, 2026
068c10c
Merge branch 'pw/rename-to-get-current-worktree'
gitster May 17, 2026
d17a7b8
Merge branch 'hn/git-checkout-m-with-stash'
gitster May 17, 2026
6d7492c
Merge branch 'rs/grep-column-only-match-fix'
gitster May 17, 2026
68aca6b
The 3rd batch
gitster May 17, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 28 additions & 7 deletions Documentation/RelNotes/2.55.0.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,13 @@ UI, Workflows & Features
to a remote repository are mostly disabled by default, except for
ANSI color escape sequences.

* "ort" merge backend improvements.

* "git checkout -m another-branch" was invented to deal with local
changes to paths that are different between the current and the new
branch, but it gave only one chance to resolve conflicts. The command
was taught to create a stash to save the local changes.


Performance, Internal Implementation, Development Support etc.
--------------------------------------------------------------
Expand Down Expand Up @@ -45,20 +52,34 @@ Fixes since v2.54
* Revert a recent change that introduced a regression to help mksh users.
(merge 8b44deebaf jk/revert-aa-reap-transport-child-processes later to maint).

* Other code cleanup, docfix, build fix, etc.
(merge 80f4b802e9 ja/doc-difftool-synopsis-style later to maint).
(merge b96490241e jc/doc-timestamps-in-stat later to maint).

* Update various GitHub Actions versions.
(merge 4a6ed9d09f js/ci-github-actions-update later to maint).

* Avoid hitting the pathname limit for socks proxy socket during the
test..
(merge b33bea27a2 js/t5564-socks-use-short-path later to maint).

* Test fix.
(merge 66ae1a48ec jc/t5551-fix-expensive later to maint).

* To help Windows 10 installations, avoid removing files whose
contents are still mmap()'ed.
(merge 4bb086cfa2 js/maintenance-fix-deadlock-on-win10 later to maint).

* The 'git backfill' command now rejects revision-limiting options that
are incompatible with its operation, uses standard documentation for
revision ranges, and includes blobs from boundary commits by default
to improve performance of subsequent operations.
(merge a1ad4a0fca en/backfill-fixes-and-edges later to maint).

* "git grep" update.
(merge 9ff4b5ab1b rs/grep-column-only-match-fix later to maint).

* Headers from glibc 2.43 when used with clang does not allow
disabling C11 language features, causing build failures..
(merge 0a6d29090c ps/clang-w-glibc-2.43-and-_Generic later to maint).

* Other code cleanup, docfix, build fix, etc.
(merge 80f4b802e9 ja/doc-difftool-synopsis-style later to maint).
(merge b96490241e jc/doc-timestamps-in-stat later to maint).
(merge 66ae1a48ec jc/t5551-fix-expensive later to maint).
(merge ef85286e51 ss/t7004-unhide-git-failures later to maint).
(merge 7584d10bc2 mf/format-patch-cover-letter-format-docfix later to maint).
(merge 8547908eb3 pw/rename-to-get-current-worktree later to maint).
2 changes: 1 addition & 1 deletion Documentation/config/format.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ format.coverLetter::
Default is false.

format.commitListFormat::
When the `--cover-letter-format` option is not given, `format-patch`
When the `--commit-list-format` option is not given, `format-patch`
uses the value of this variable to decide how to format the entry of
each commit. Defaults to `shortlog`.

Expand Down
22 changes: 19 additions & 3 deletions Documentation/git-backfill.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ git-backfill - Download missing objects in a partial clone
SYNOPSIS
--------
[synopsis]
git backfill [--min-batch-size=<n>] [--[no-]sparse]
git backfill [--min-batch-size=<n>] [--[no-]sparse] [--[no-]include-edges] [<revision-range>]

DESCRIPTION
-----------
Expand Down Expand Up @@ -43,7 +43,7 @@ smaller network calls than downloading the entire repository at clone
time.

By default, `git backfill` downloads all blobs reachable from the `HEAD`
commit. This set can be restricted or expanded using various options.
commit. This set can be restricted or expanded using various options below.

THIS COMMAND IS EXPERIMENTAL. ITS BEHAVIOR MAY CHANGE IN THE FUTURE.

Expand All @@ -63,7 +63,23 @@ OPTIONS
current sparse-checkout. If the sparse-checkout feature is enabled,
then `--sparse` is assumed and can be disabled with `--no-sparse`.

You may also specify the commit limiting options from linkgit:git-rev-list[1].
`--include-edges`::
`--no-include-edges`::
Include blobs from boundary commits in the backfill. Useful in
preparation for commands like `git log -p A..B` or `git replay
--onto TARGET A..B`, where A..B normally excludes A but you need
the blobs from A as well. `--include-edges` is the default.

`<revision-range>`::
Backfill only blobs reachable from commits in the specified
revision range. When no _<revision-range>_ is specified, it
defaults to `HEAD` (i.e. the whole history leading to the
current commit). For a complete list of ways to spell
_<revision-range>_, see the "Specifying Ranges" section of
linkgit:gitrevisions[7].
+
You may also use commit-limiting options understood by
linkgit:git-rev-list[1] such as `--first-parent`, `--since`, or pathspecs.

SEE ALSO
--------
Expand Down
55 changes: 26 additions & 29 deletions Documentation/git-checkout.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -251,20 +251,19 @@ working tree, by copying them from elsewhere, extracting a tarball, etc.
are different between the current branch and the branch to
which you are switching, the command refuses to switch
branches in order to preserve your modifications in context.
However, with this option, a three-way merge between the current
branch, your working tree contents, and the new branch
is done, and you will be on the new branch.
+
When a merge conflict happens, the index entries for conflicting
paths are left unmerged, and you need to resolve the conflicts
and mark the resolved paths with `git add` (or `git rm` if the merge
should result in deletion of the path).
With this option, the conflicting local changes are
automatically stashed before the switch and reapplied
afterwards. If the local changes do not overlap with the
differences between branches, the switch proceeds without
stashing. If reapplying the stash results in conflicts, the
entry is saved to the stash list. Resolve the conflicts
and run `git stash drop` when done, or clear the working
tree (e.g. with `git reset --hard`) before running `git stash
pop` later to re-apply your changes.
+
When checking out paths from the index, this option lets you recreate
the conflicted merge in the specified paths. This option cannot be
used when checking out paths from a tree-ish.
+
When switching branches with `--merge`, staged changes may be lost.

`--conflict=<style>`::
The same as `--merge` option above, but changes the way the
Expand Down Expand Up @@ -578,38 +577,36 @@ $ git checkout mytopic
error: You have local changes to 'frotz'; not switching branches.
------------

You can give the `-m` flag to the command, which would try a
three-way merge:
You can give the `-m` flag to the command, which will carry your local
changes to the new branch:

------------
$ git checkout -m mytopic
Auto-merging frotz
Applied autostash.
Switched to branch 'mytopic'
The following paths have local changes:
M frotz
------------

After this three-way merge, the local modifications are _not_
After the switch, the local modifications are reapplied and are _not_
registered in your index file, so `git diff` would show you what
changes you made since the tip of the new branch.

=== 3. Merge conflict

When a merge conflict happens during switching branches with
the `-m` option, you would see something like this:
When the `--merge` (`-m`) option is given and the local changes
overlap with the changes in the branch we're switching to, the
changes are stashed and reapplied after the switch. If this
process results in conflicts, the stash entry is saved and a
message is printed:

------------
$ git checkout -m mytopic
Auto-merging frotz
ERROR: Merge conflict in frotz
fatal: merge program failed
------------

At this point, `git diff` shows the changes cleanly merged as in
the previous example, as well as the changes in the conflicted
files. Edit and resolve the conflict and mark it resolved with
`git add` as usual:

------------
$ edit frotz
$ git add frotz
Your local changes are stashed, however applying them
resulted in conflicts. You can either resolve the conflicts
and then discard the stash with "git stash drop", or, if you
do not want to resolve them now, run "git reset --hard" and
apply the local changes later by running "git stash pop".
------------

CONFIGURATION
Expand Down
11 changes: 10 additions & 1 deletion Documentation/git-stash.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ git stash list [<log-options>]
git stash show [-u | --include-untracked | --only-untracked] [<diff-options>] [<stash>]
git stash drop [-q | --quiet] [<stash>]
git stash pop [--index] [-q | --quiet] [<stash>]
git stash apply [--index] [-q | --quiet] [<stash>]
git stash apply [--index] [-q | --quiet] [--label-ours=<label>] [--label-theirs=<label>] [--label-base=<label>] [<stash>]
git stash branch <branchname> [<stash>]
git stash [push] [-p | --patch] [-S | --staged] [-k | --[no-]keep-index] [-q | --quiet]
[-u | --include-untracked] [-a | --all] [(-m | --message) <message>]
Expand Down Expand Up @@ -195,6 +195,15 @@ the index's ones. However, this can fail, when you have conflicts
(which are stored in the index, where you therefore can no longer
apply the changes as they were originally).

`--label-ours=<label>`::
`--label-theirs=<label>`::
`--label-base=<label>`::
These options are only valid for the `apply` command.
+
Use the given labels in conflict markers instead of the default
"Updated upstream", "Stashed changes", and "Stash base".
`--label-base` only has an effect with merge.conflictStyle=diff3.

`-k`::
`--keep-index`::
`--no-keep-index`::
Expand Down
36 changes: 20 additions & 16 deletions Documentation/git-switch.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -123,18 +123,19 @@ variable.

`-m`::
`--merge`::
If you have local modifications to one or more files that are
different between the current branch and the branch to which
you are switching, the command refuses to switch branches in
order to preserve your modifications in context. However,
with this option, a three-way merge between the current
branch, your working tree contents, and the new branch is
done, and you will be on the new branch.
+
When a merge conflict happens, the index entries for conflicting
paths are left unmerged, and you need to resolve the conflicts
and mark the resolved paths with `git add` (or `git rm` if the merge
should result in deletion of the path).
If you have local modifications to one or more files that
are different between the current branch and the branch to
which you are switching, the command normally refuses to
switch branches in order to preserve your modifications in
context. However, with this option, the conflicting local
changes are automatically stashed before the switch and
reapplied afterwards. If the local changes do not overlap
with the differences between branches, the switch proceeds
without stashing. If reapplying the stash results in
conflicts, the entry is saved to the stash list. Resolve
the conflicts and run `git stash drop` when done, or clear
the working tree (e.g. with `git reset --hard`) before
running `git stash pop` later to re-apply your changes.

`--conflict=<style>`::
The same as `--merge` option above, but changes the way the
Expand Down Expand Up @@ -217,15 +218,18 @@ $ git switch mytopic
error: You have local changes to 'frotz'; not switching branches.
------------

You can give the `-m` flag to the command, which would try a three-way
merge:
You can give the `-m` flag to the command, which will carry your local
changes to the new branch:

------------
$ git switch -m mytopic
Auto-merging frotz
Applied autostash.
Switched to branch 'mytopic'
The following paths have local changes:
M frotz
------------

After this three-way merge, the local modifications are _not_
After the switch, the local modifications are reapplied and are _not_
registered in your index file, so `git diff` would show you what
changes you made since the tip of the new branch.

Expand Down
31 changes: 30 additions & 1 deletion builtin/backfill.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
#include "path-walk.h"

static const char * const builtin_backfill_usage[] = {
N_("git backfill [--min-batch-size=<n>] [--[no-]sparse]"),
N_("git backfill [--min-batch-size=<n>] [--[no-]sparse] [--[no-]include-edges] [<revision-range>]"),
NULL
};

Expand All @@ -35,6 +35,7 @@ struct backfill_context {
struct oid_array current_batch;
size_t min_batch_size;
int sparse;
int include_edges;
struct rev_info revs;
};

Expand Down Expand Up @@ -78,6 +79,28 @@ static int fill_missing_blobs(const char *path UNUSED,
return 0;
}

static void reject_unsupported_rev_list_options(struct rev_info *revs)
{
if (revs->diffopt.pickaxe)
die(_("'%s' cannot be used with 'git backfill'"),
(revs->diffopt.pickaxe_opts & DIFF_PICKAXE_REGEX) ? "-G" : "-S");
if (revs->diffopt.filter || revs->diffopt.filter_not)
die(_("'%s' cannot be used with 'git backfill'"),
"--diff-filter");
if (revs->diffopt.flags.follow_renames)
die(_("'%s' cannot be used with 'git backfill'"),
"--follow");
if (revs->line_level_traverse)
die(_("'%s' cannot be used with 'git backfill'"),
"-L");
if (revs->explicit_diff_merges)
die(_("'%s' cannot be used with 'git backfill'"),
"--diff-merges");
if (revs->filter.choice)
die(_("'%s' cannot be used with 'git backfill'"),
"--filter");
}

static int do_backfill(struct backfill_context *ctx)
{
struct path_walk_info info = PATH_WALK_INFO_INIT;
Expand All @@ -94,6 +117,8 @@ static int do_backfill(struct backfill_context *ctx)
/* Walk from HEAD if otherwise unspecified. */
if (!ctx->revs.pending.nr)
add_head_to_pending(&ctx->revs);
if (ctx->include_edges)
ctx->revs.edge_hint = 1;

info.blobs = 1;
info.tags = info.commits = info.trees = 0;
Expand Down Expand Up @@ -121,12 +146,15 @@ int cmd_backfill(int argc, const char **argv, const char *prefix, struct reposit
.min_batch_size = 50000,
.sparse = -1,
.revs = REV_INFO_INIT,
.include_edges = 1,
};
struct option options[] = {
OPT_UNSIGNED(0, "min-batch-size", &ctx.min_batch_size,
N_("Minimum number of objects to request at a time")),
OPT_BOOL(0, "sparse", &ctx.sparse,
N_("Restrict the missing objects to the current sparse-checkout")),
OPT_BOOL(0, "include-edges", &ctx.include_edges,
N_("Include blobs from boundary commits in the backfill")),
OPT_END(),
};
struct repo_config_values *cfg = repo_config_values(the_repository);
Expand All @@ -144,6 +172,7 @@ int cmd_backfill(int argc, const char **argv, const char *prefix, struct reposit

if (argc > 1)
die(_("unrecognized argument: %s"), argv[1]);
reject_unsupported_rev_list_options(&ctx.revs);

repo_config(repo, git_default_config, NULL);

Expand Down
Loading