Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
f42d7c9
Merge branch 'kh/replay-invalid-onto-advance' into ps/history
gitster Jan 8, 2026
1454743
builtin/replay: extract core logic to replay revisions
pks-t Jan 13, 2026
6aeda3c
builtin/replay: move core logic into "libgit.a"
pks-t Jan 13, 2026
410e378
replay: small set of cleanups
pks-t Jan 13, 2026
5425771
replay: support empty commit ranges
pks-t Jan 13, 2026
48a72f6
replay: support updating detached HEAD
pks-t Jan 13, 2026
475ade1
wt-status: provide function to expose status for trees
pks-t Jan 13, 2026
a675183
builtin: add new "history" command
pks-t Jan 13, 2026
d205234
builtin/history: implement "reword" subcommand
pks-t Jan 13, 2026
9e4a786
Merge branch 'ps/history' into pw/replay-drop-empty
gitster Jan 13, 2026
0ee71f4
replay: drop commits that become empty
phillipwood Dec 18, 2025
b52a28b
refs: skip to next ref when current ref is rejected
KarthikNayak Jan 25, 2026
be54b10
refs: add rejection detail to the callback function
KarthikNayak Jan 25, 2026
a366bde
update-ref: utilize rejected error details if available
KarthikNayak Jan 25, 2026
274f435
fetch: utilize rejected ref error details
KarthikNayak Jan 25, 2026
2ea49f2
receive-pack: utilize rejected ref error details
KarthikNayak Jan 25, 2026
eff9299
fetch: delay user information post committing of transaction
KarthikNayak Jan 25, 2026
6f5ca70
worktree: clarify that --expire only affects missing worktrees
sambostock Jan 28, 2026
208642c
u-string-list: add unit tests for string-list methods
amishhaa Jan 29, 2026
2e711ac
string-list: add string_list_sort_u() that mimics "sort -u"
amishhaa Jan 29, 2026
8466efa
t/perf/p3400: speed up setup using fast-import
malon7782 Jan 30, 2026
7bf3785
Merge branch 'ps/history'
gitster Feb 9, 2026
8087aae
Merge branch 'pw/replay-drop-empty'
gitster Feb 9, 2026
6176ee2
Merge branch 'kn/ref-batch-output-error-reporting-fix'
gitster Feb 9, 2026
4f39292
Merge branch 'sb/doc-worktree-prune-expire-improvement'
gitster Feb 9, 2026
35e17b2
Merge branch 'ac/string-list-sort-u-and-tests'
gitster Feb 9, 2026
6a3c66d
Merge branch 'ty/perf-3400-optim'
gitster Feb 9, 2026
864f55e
The second batch
gitster Feb 9, 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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@
/git-grep
/git-hash-object
/git-help
/git-history
/git-hook
/git-http-backend
/git-http-fetch
Expand Down
21 changes: 21 additions & 0 deletions Documentation/RelNotes/2.54.0.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,17 @@ UI, Workflows & Features
* "git add -p" and friends note what the current status of the hunk
being shown is.

* "git history" history rewriting (experimental) command has been
added.


* "git replay" is taught to drop commits that become empty (not the
ones that are empty in the original).

* The help text and the documentation for the "--expire" option of
"git worktree [list|prune]" have been improved.



Performance, Internal Implementation, Development Support etc.
--------------------------------------------------------------
Expand All @@ -15,6 +26,11 @@ Performance, Internal Implementation, Development Support etc.
each other by encoding submodule names before using them as path
components.

* The string_list API gains a new helper, string_list_sort_u(), and
new unit tests to extend coverage.

* Improve set-up time of a perf test.


Fixes since v2.53
-----------------
Expand All @@ -31,6 +47,11 @@ Fixes since v2.53
"-z") in the "git last-modified" command have been updated.
(merge 9dcc09bed1 tc/last-modified-options-cleanup later to maint).

* A handful of code paths that started using batched ref update API
(after Git 2.51 or so) lost detailed error output, which have been
corrected.
(merge eff9299eac kn/ref-batch-output-error-reporting-fix later to maint).

* Other code cleanup, docfix, build fix, etc.
(merge d79fff4a11 jk/remote-tracking-ref-leakfix later to maint).
(merge 7a747f972d dd/t5403-modernise later to maint).
Expand Down
73 changes: 73 additions & 0 deletions Documentation/git-history.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
git-history(1)
==============

NAME
----
git-history - EXPERIMENTAL: Rewrite history

SYNOPSIS
--------
[synopsis]
git history reword <commit> [--ref-action=(branches|head|print)]

DESCRIPTION
-----------

Rewrite history by rearranging or modifying specific commits in the
history.

THIS COMMAND IS EXPERIMENTAL. THE BEHAVIOR MAY CHANGE.

This command is related to linkgit:git-rebase[1] in that both commands can be
used to rewrite history. There are a couple of major differences though:

* linkgit:git-history[1] can work in a bare repository as it does not need to
touch either the index or the worktree.
* linkgit:git-history[1] does not execute any linkgit:githooks[5] at the
current point in time. This may change in the future.
* linkgit:git-history[1] by default updates all branches that are descendants
of the original commit to point to the rewritten commit.

Overall, linkgit:git-history[1] aims to provide a more opinionated way to modify
your commit history that is simpler to use compared to linkgit:git-rebase[1] in
general.

Use linkgit:git-rebase[1] if you want to reapply a range of commits onto a
different base, or interactive rebases if you want to edit a range of commits
at once.

LIMITATIONS
-----------

This command does not (yet) work with histories that contain merges. You
should use linkgit:git-rebase[1] with the `--rebase-merges` flag instead.

Furthermore, the command does not support operations that can result in merge
conflicts. This limitation is by design as history rewrites are not intended to
be stateful operations. The limitation can be lifted once (if) Git learns about
first-class conflicts.

COMMANDS
--------

The following commands are available to rewrite history in different ways:

`reword <commit>`::
Rewrite the commit message of the specified commit. All the other
details of this commit remain unchanged. This command will spawn an
editor with the current message of that commit.

OPTIONS
-------

`--ref-action=(branches|head|print)`::
Control which references will be updated by the command, if any. With
`branches`, all local branches that point to commits which are
descendants of the original commit will be rewritten. With `head`, only
the current `HEAD` reference will be rewritten. With `print`, all
updates as they would be performed with `branches` are printed in a
format that can be consumed by linkgit:git-update-ref[1].

GIT
---
Part of the linkgit:git[1] suite
4 changes: 3 additions & 1 deletion Documentation/git-replay.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,9 @@ The default mode can be configured via the `replay.refAction` configuration vari
Range of commits to replay; see "Specifying Ranges" in
linkgit:git-rev-parse[1]. In `--advance <branch>` mode, the
range should have a single tip, so that it's clear to which tip the
advanced <branch> should point.
advanced <branch> should point. Any commits in the range whose
changes are already present in the branch the commits are being
replayed onto will be dropped.

:git-replay: 1
include::rev-list-options.adoc[]
Expand Down
10 changes: 8 additions & 2 deletions Documentation/git-worktree.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,13 @@ with linked worktrees if you move the main worktree manually.)

`prune`::

Prune worktree information in `$GIT_DIR/worktrees`.
Remove worktree information in `$GIT_DIR/worktrees` for worktrees
whose working trees are missing. Useful after manually removing
a working tree that is no longer needed (but use "git worktree
remove" next time you want to do so). Also, if you _moved_ a
working tree elsewhere causing the worktree information to become
dangling, see "git worktree repair" to reconnect the worktree to
the new working tree location.

`remove`::

Expand Down Expand Up @@ -271,7 +277,7 @@ mismatch, even if the links are correct.
With `list`, output additional information about worktrees (see below).

`--expire <time>`::
With `prune`, only expire unused worktrees older than _<time>_.
With `prune`, only prune missing worktrees if older than _<time>_.
+
With `list`, annotate missing worktrees as prunable if they are older than
_<time>_.
Expand Down
1 change: 1 addition & 0 deletions Documentation/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ manpages = {
'git-gui.adoc' : 1,
'git-hash-object.adoc' : 1,
'git-help.adoc' : 1,
'git-history.adoc' : 1,
'git-hook.adoc' : 1,
'git-http-backend.adoc' : 1,
'git-http-fetch.adoc' : 1,
Expand Down
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -1285,6 +1285,7 @@ LIB_OBJS += repack-geometry.o
LIB_OBJS += repack-midx.o
LIB_OBJS += repack-promisor.o
LIB_OBJS += replace-object.o
LIB_OBJS += replay.o
LIB_OBJS += repo-settings.o
LIB_OBJS += repository.o
LIB_OBJS += rerere.o
Expand Down Expand Up @@ -1417,6 +1418,7 @@ BUILTIN_OBJS += builtin/get-tar-commit-id.o
BUILTIN_OBJS += builtin/grep.o
BUILTIN_OBJS += builtin/hash-object.o
BUILTIN_OBJS += builtin/help.o
BUILTIN_OBJS += builtin/history.o
BUILTIN_OBJS += builtin/hook.o
BUILTIN_OBJS += builtin/index-pack.o
BUILTIN_OBJS += builtin/init-db.o
Expand Down
1 change: 1 addition & 0 deletions builtin.h
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ int cmd_get_tar_commit_id(int argc, const char **argv, const char *prefix, struc
int cmd_grep(int argc, const char **argv, const char *prefix, struct repository *repo);
int cmd_hash_object(int argc, const char **argv, const char *prefix, struct repository *repo);
int cmd_help(int argc, const char **argv, const char *prefix, struct repository *repo);
int cmd_history(int argc, const char **argv, const char *prefix, struct repository *repo);
int cmd_hook(int argc, const char **argv, const char *prefix, struct repository *repo);
int cmd_index_pack(int argc, const char **argv, const char *prefix, struct repository *repo);
int cmd_init_db(int argc, const char **argv, const char *prefix, struct repository *repo);
Expand Down
3 changes: 1 addition & 2 deletions builtin/clone.c
Original file line number Diff line number Diff line change
Expand Up @@ -1136,8 +1136,7 @@ int cmd_clone(int argc,
int val;

/* remove duplicates */
string_list_sort(&option_recurse_submodules);
string_list_remove_duplicates(&option_recurse_submodules, 0);
string_list_sort_u(&option_recurse_submodules, 0);

/*
* NEEDSWORK: In a multi-working-tree world, this needs to be
Expand Down
3 changes: 1 addition & 2 deletions builtin/fast-export.c
Original file line number Diff line number Diff line change
Expand Up @@ -1118,8 +1118,7 @@ static void get_tags_and_duplicates(struct rev_cmdline_info *info)
free(full_name);
}

string_list_sort(&extra_refs);
string_list_remove_duplicates(&extra_refs, 0);
string_list_sort_u(&extra_refs, 0);
}

static void handle_tags_and_duplicates(struct string_list *extras)
Expand Down
Loading