* Re: [PATCH] ci: upgrade to using macos-13
From: Junio C Hamano @ 2023-11-03 8:16 UTC (permalink / raw)
To: Johannes Schindelin via GitGitGadget; +Cc: git, Johannes Schindelin
In-Reply-To: <pull.1607.git.1698996455218.gitgitgadget@gmail.com>
"Johannes Schindelin via GitGitGadget" <gitgitgadget@gmail.com>
writes:
> From: Johannes Schindelin <johannes.schindelin@gmx.de>
>
> In April, GitHub announced that the `macos-13` pool is available:
> https://github.blog/changelog/2023-04-24-github-actions-macos-13-is-now-available/.
> It is only a matter of time until the `macos-12` pool is going away,
> therefore we should switch now, without pressure of a looming deadline.
> ...
> To reinstate the spirit of that commit _and_ to fix that build failure,
> let's switch to the now-newest GCC version: v13.x.
Thank you very much for a well reasoned patch that is very timely.
I am tempted to fast-track this one down from 'seen' to 'maint'
before we tag -rc1.
Will queue.
^ permalink raw reply
* [PATCH] ci: upgrade to using macos-13
From: Johannes Schindelin via GitGitGadget @ 2023-11-03 7:27 UTC (permalink / raw)
To: git; +Cc: Johannes Schindelin, Johannes Schindelin
From: Johannes Schindelin <johannes.schindelin@gmx.de>
In April, GitHub announced that the `macos-13` pool is available:
https://github.blog/changelog/2023-04-24-github-actions-macos-13-is-now-available/.
It is only a matter of time until the `macos-12` pool is going away,
therefore we should switch now, without pressure of a looming deadline.
Since the `macos-13` runners no longer include Python2, we also drop
specifically testing with Python2 and switch uniformly to Python3, see
https://github.com/actions/runner-images/blob/HEAD/images/macos/macos-13-Readme.md
for details about the software available on the `macos-13` pool's
runners.
Also, on macOS 13, Homebrew seems to install a `gcc@9` package that no
longer comes with a regular `unistd.h` (there seems only to be a
`ssp/unistd.h`), and hence builds would fail with:
In file included from base85.c:1:
git-compat-util.h:223:10: fatal error: unistd.h: No such file or directory
223 | #include <unistd.h>
| ^~~~~~~~~~
compilation terminated.
The reason why we install GCC v9.x explicitly is historical, and back in
the days it was because it was the _newest_ version available via
Homebrew: 176441bfb58 (ci: build Git with GCC 9 in the 'osx-gcc' build
job, 2019-11-27).
To reinstate the spirit of that commit _and_ to fix that build failure,
let's switch to the now-newest GCC version: v13.x.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
ci: upgrade to using macos-13
GitHub announced in April that the macos-13 pool is available
[https://github.blog/changelog/2023-04-24-github-actions-macos-13-is-now-available/],
so let's switch. This might also stave off CI failures we experience
over in GitGitGadget (e.g. here
[https://github.com/gitgitgadget/git/actions/runs/6729366919/job/18290134547#step:3:56])
and in Git for Windows (e.g. here
[https://github.com/git-for-windows/git/actions/runs/6708618181/job/18252834721#step:3:57])
where occasionally macos-12-xl runners seem to be co-opted to cope with
macos-12 workload (and the former don't have Python2 in their PATH).
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1607%2Fdscho%2Fswitch-ci-to-macos-13-v1
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1607/dscho/switch-ci-to-macos-13-v1
Pull-Request: https://github.com/gitgitgadget/git/pull/1607
.github/workflows/main.yml | 6 +++---
ci/lib.sh | 6 ++----
2 files changed, 5 insertions(+), 7 deletions(-)
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index dcf7d78f1d0..9fdbd540289 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -276,11 +276,11 @@ jobs:
pool: ubuntu-20.04
- jobname: osx-clang
cc: clang
- pool: macos-12
+ pool: macos-13
- jobname: osx-gcc
cc: gcc
- cc_package: gcc-9
- pool: macos-12
+ cc_package: gcc-13
+ pool: macos-13
- jobname: linux-gcc-default
cc: gcc
pool: ubuntu-latest
diff --git a/ci/lib.sh b/ci/lib.sh
index 6fbb5bade12..bc0b23099df 100755
--- a/ci/lib.sh
+++ b/ci/lib.sh
@@ -253,11 +253,9 @@ ubuntu-*)
export PATH="$GIT_LFS_PATH:$P4_PATH:$PATH"
;;
macos-*)
- if [ "$jobname" = osx-gcc ]
+ MAKEFLAGS="$MAKEFLAGS PYTHON_PATH=$(which python3)"
+ if [ "$jobname" != osx-gcc ]
then
- MAKEFLAGS="$MAKEFLAGS PYTHON_PATH=$(which python3)"
- else
- MAKEFLAGS="$MAKEFLAGS PYTHON_PATH=$(which python2)"
MAKEFLAGS="$MAKEFLAGS APPLE_COMMON_CRYPTO_SHA1=Yes"
fi
;;
base-commit: 692be87cbba55e8488f805d236f2ad50483bd7d5
--
gitgitgadget
^ permalink raw reply related
* RE: General question about "git range-diff"
From: Robin Dos Anjos @ 2023-11-03 1:25 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git@vger.kernel.org
In-Reply-To: <xmqqbkcblp1y.fsf@gitster.g>
Thank you both for your very quick answers and recommendations! I will check your links. That sounds really interesting.
I'm happy to hear that you don't find my suggestion entirely stupid. My use case is so specific that I wasn't sure it would be very relevant as a feature request.
I will probably take a look at the source code too. But to be very honest, my experience with C is quite limited. I have the basics, but I never practiced it in a real world project. So a codebase such as git's will be way more intimidating to me than sending a message to this mailing list. Building git from the sources would be a good start.
It would be an immense honor for me to invest some time to add a feature to git. But adding this mode to "git range-diff" is probably very ambitious and not very beginner-friendly. I will check the code and see how it goes. We never know!
If you have further recommendations to start this journey, I will be very happy to hear them, of course. Thank you again!
^ permalink raw reply
* Re: [PATCH 1/1] attr: enable attr pathspec magic for git-add and git-stash
From: Junio C Hamano @ 2023-11-02 23:45 UTC (permalink / raw)
To: Joanna Wang; +Cc: git
In-Reply-To: <xmqqil6jlu3m.fsf@gitster.g>
Junio C Hamano <gitster@pobox.com> writes:
>> + } else {
>> + /* For an element in longhand form, we simply copy everything up to the final ')' */
>
> A comment that is a bit on the overly-long side.
>
>> + int len = strchr(element, ')') - element;
>> + strbuf_add(sb, element, len);
In practice, nobody sane would write a pathspec magic that is over
2GB in size, so this would not matter unless we are facing a
potential attacker, but as the third parameter strbuf_add() takes is
of type size_t, it would not hurt to define "len" as the same type
as well.
> Thanks for working on fixing this rather old bug. I think we should
> have noticed when we added the support for the "attr" magic to the
> pathspec API.
^ permalink raw reply
* Re: [PATCH] strvec: drop unnecessary include of hex.h
From: Junio C Hamano @ 2023-11-02 23:25 UTC (permalink / raw)
To: Linus Arver via GitGitGadget; +Cc: git, Jonathan Tan, Calvin Wan, Linus Arver
In-Reply-To: <pull.1608.git.1698958277454.gitgitgadget@gmail.com>
"Linus Arver via GitGitGadget" <gitgitgadget@gmail.com> writes:
> From: Linus Arver <linusa@google.com>
>
> In 41771fa435 (cache.h: remove dependence on hex.h; make other files
> include it explicitly, 2023-02-24) we added this as part of a larger
> mechanical refactor. But strvec doesn't actually depend on hex.h, so
> remove it.
>
> Signed-off-by: Linus Arver <linusa@google.com>
> ---
> strvec: drop unnecessary include of hex.h
>
> In 41771fa435 (cache.h: remove dependence on hex.h; make other files
> include it explicitly, 2023-02-24) we added this as part of a larger
> mechanical refactor. But strvec doesn't actually depend on hex.h, so
> remove it.
This change somehow looks familiar.
> Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1608%2Flistx%2Fstrvec-cleanup-v1
> Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1608/listx/strvec-cleanup-v1
> Pull-Request: https://github.com/gitgitgadget/git/pull/1608
>
> strvec.c | 1 -
> 1 file changed, 1 deletion(-)
>
> diff --git a/strvec.c b/strvec.c
> index 89dc9e7e753..178f4f37480 100644
> --- a/strvec.c
> +++ b/strvec.c
> @@ -1,6 +1,5 @@
> #include "git-compat-util.h"
> #include "strvec.h"
> -#include "hex.h"
> #include "strbuf.h"
Makes sense.
Will queue.
Thanks.
^ permalink raw reply
* Re: General question about "git range-diff"
From: Junio C Hamano @ 2023-11-02 23:21 UTC (permalink / raw)
To: Robin Dos Anjos; +Cc: git@vger.kernel.org
In-Reply-To: <PR3P195MB087847E68AD2032148EFCA039BA6A@PR3P195MB0878.EURP195.PROD.OUTLOOK.COM>
Robin Dos Anjos <robin_1997@hotmail.fr> writes:
> There are several workarounds to this situation.
It would be much better to avoid getting into a problematic
situation in the first place than having to come up with a
workaround for such a situation.
"git imerge" may be a good tool to know about for that. You may be
able to avoid having to say: "Gaahh, I am not patient enough to
rebase this series of commits, even though I spent time to carefully
separate into logical and independent steps. I'll squash them all
into one large blob of changes, even though it means I will lose all
that work."
An "interdiff" that compares the base and the tip of the old and the
new iterations is certainly a way to compare the changes as a whole,
in exchange for loss of the diff between the log messages and other
commit metadata. Adding such a mode to the "range-diff" command
might not be a bad idea.
^ permalink raw reply
* Re: General question about "git range-diff"
From: brian m. carlson @ 2023-11-02 21:48 UTC (permalink / raw)
To: Robin Dos Anjos; +Cc: git@vger.kernel.org
In-Reply-To: <PR3P195MB087847E68AD2032148EFCA039BA6A@PR3P195MB0878.EURP195.PROD.OUTLOOK.COM>
[-- Attachment #1: Type: text/plain, Size: 2022 bytes --]
On 2023-11-02 at 18:56:39, Robin Dos Anjos wrote:
> Hi git community!
Hi,
> I'm a bit intimidated as this is my first message in the mailing list but I'll give it a go!
No reason to be intimidated. We're very friendly here.
> This is so useful to me that I'm wondering why "git range-diff" does
> not implement this behavior. We could imagine a flag that would make
> it behave as I described. Is this something that was ever considered?
> Are there any technical difficulties that I'm completely missing? Do
> you think this could be helpful to other people?
I'm not the author of range-diff, but I believe it was based on an
earlier tool named git-tbdiff[0], which had similar behaviour and
similar limitations. My guess as to why nobody implemented a feature to
handle the squashed commits case is that typically the recommended
workflow in Git is to write small independent, logical, well-described,
bisectable commits, and squashing is not recommended because it destroys
all the work that people have put into making nice commits.
Of course, in many situations, people don't write nice commits like
that, and many commits are effectively fixup commits with very short
messages (e.g. "make it work"), sometimes containing profanity directed
at the computer, and in those environments, squashing may be a
legitimate choice. However, it isn't typically a workflow that gets a
lot of focus because most tooling is focused on the more recommended
approach.
Having said that, I'm sure people would find a feature like you
suggested useful, although I'm not likely to use it myself. It's
possible that somebody might see your message and implement it, but
usually patches come in from people who feel strongly about a feature
and implement it themselves. If you feel like you'd like to try such a
change, I'm sure you can find folks to review it and provide feedback.
[0] https://github.com/trast/tbdiff
--
brian m. carlson (he/him or they/them)
Toronto, Ontario, CA
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 262 bytes --]
^ permalink raw reply
* Re: [PATCH 1/1] attr: enable attr pathspec magic for git-add and git-stash
From: Junio C Hamano @ 2023-11-02 21:32 UTC (permalink / raw)
To: Joanna Wang; +Cc: git
In-Reply-To: <20231102175316.2229631-1-jojwang@google.com>
Joanna Wang <jojwang@google.com> writes:
>> Indeed, if you are going to pass the original "elt" string *anyway*,
>> you have all the info in there that you need. I wonder if it makes
>> sense to get rid of the "unsigned magic" bitset from the parameter,
> This was my initial strategy but ran into trouble when the magic was
> in shorthand form. Upon closer look at how the shorthand works
> (e.g. shorthand and longhand can never mix so
> ':!/(attr:chicken)file' would make <(attr:chicken)file> the match string)
> I tried this again by processing the forms separately.
> It would still need both the element and element_magic, but I think it
> addresses the concerns with future changes where multiple magic match
> values could be allowed and the match values could be any string.
The "bits" were acceptable for things like "exclude" and "icase"
because it does not matter how many times you gave them and they do
not take any additional parameters, but attr is different in that it
takes a value, and multiple instances with different values can be
given. It is lucky that we did not allow mixing the short and long
forms ;-)
> These changes would be fine as long as there is no overlap between
> magic that takes a user-supplied value and magic that can be
> expressed in shorthand.
Indeed. Thanks for thinking this through.
> -static void prefix_magic(struct strbuf *sb, int prefixlen, unsigned magic)
> +static void prefix_magic(struct strbuf *sb, int prefixlen, unsigned magic, const char *element)
> {
> - int i;
> - strbuf_addstr(sb, ":(");
> - for (i = 0; i < ARRAY_SIZE(pathspec_magic); i++)
> - if (magic & pathspec_magic[i].bit) {
> - if (sb->buf[sb->len - 1] != '(')
> - strbuf_addch(sb, ',');
> - strbuf_addstr(sb, pathspec_magic[i].name);
At this point in the code, is it guaranteed that element[0] is ':'
and never a NUL? Also is it guaranteed that element has ')'
somewhere later if element[1] is '('?
"Otherwise the caller would have failed to parse the pathspec magic
into the magic bits, and this helper function would not have been
called" is the answer I am expecting, but I didn't check if the
caller refrains from calling us. It would be better to have a brief
comment explaining why a seemingly loose parsing of element[] string
is OK to save future readers from wondering the same thing as I did
here.
> + if (element[1] != '(') {
> + /* Process an element in shorthand form (e.g. ":!/<match>") */
> + strbuf_addstr(sb, ":(");
> + for (int i = 0; i < ARRAY_SIZE(pathspec_magic); i++) {
> + if ((magic & pathspec_magic[i].bit) && (pathspec_magic[i].mnemonic != '\0')) {
> + if (sb->buf[sb->len - 1] != '(')
> + strbuf_addch(sb, ',');
> + strbuf_addstr(sb, pathspec_magic[i].name);
> + }
> }
> + } else {
> + /* For an element in longhand form, we simply copy everything up to the final ')' */
A comment that is a bit on the overly-long side.
> + int len = strchr(element, ')') - element;
> + strbuf_add(sb, element, len);
> + }
> strbuf_addf(sb, ",prefix:%d)", prefixlen);
> }
Come to think of it, this part of the change could stand on its own
as an independent bugfix. I wonder if this existing bug caused by
failing to copy the value of "attr:" is triggerable from a codepath
that already allows PATHSPEC_ATTR magic. Not absolutely required
when the rest of the patch is in reasonably close to the finish
line, but it would narrow the scope of the new feature proper to
treat this as a separate and independent fix, on which the new
fature depends on.
Thanks for working on fixing this rather old bug. I think we should
have noticed when we added the support for the "attr" magic to the
pathspec API.
^ permalink raw reply
* [PATCH] strvec: drop unnecessary include of hex.h
From: Linus Arver via GitGitGadget @ 2023-11-02 20:51 UTC (permalink / raw)
To: git; +Cc: Jonathan Tan, Calvin Wan, Linus Arver, Linus Arver
From: Linus Arver <linusa@google.com>
In 41771fa435 (cache.h: remove dependence on hex.h; make other files
include it explicitly, 2023-02-24) we added this as part of a larger
mechanical refactor. But strvec doesn't actually depend on hex.h, so
remove it.
Signed-off-by: Linus Arver <linusa@google.com>
---
strvec: drop unnecessary include of hex.h
In 41771fa435 (cache.h: remove dependence on hex.h; make other files
include it explicitly, 2023-02-24) we added this as part of a larger
mechanical refactor. But strvec doesn't actually depend on hex.h, so
remove it.
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1608%2Flistx%2Fstrvec-cleanup-v1
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1608/listx/strvec-cleanup-v1
Pull-Request: https://github.com/gitgitgadget/git/pull/1608
strvec.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/strvec.c b/strvec.c
index 89dc9e7e753..178f4f37480 100644
--- a/strvec.c
+++ b/strvec.c
@@ -1,6 +1,5 @@
#include "git-compat-util.h"
#include "strvec.h"
-#include "hex.h"
#include "strbuf.h"
const char *empty_strvec[] = { NULL };
base-commit: bc5204569f7db44d22477485afd52ea410d83743
--
gitgitgadget
^ permalink raw reply related
* General question about "git range-diff"
From: Robin Dos Anjos @ 2023-11-02 18:56 UTC (permalink / raw)
To: git@vger.kernel.org
Hi git community!
I'm a bit intimidated as this is my first message in the mailing list but I'll give it a go!
First, I'd like to say that I've been using git for years and I think it's a fantastic tool. I always learn new things about it. It's so powerful and great.
Git 2.19 introduced one of my favorite features: "git range-diff". I use it all the time. Whenever I rebase a branch, I check that I resolved conflicts correctly using a range-diff. I avoided many bugs using this strategy.
But there is a caveat. Sometimes, the rebased branch contains numerous commits and resolving conflicts commit by commit is painful. This is particularly true of long-lived feature branches with multiple people pushing to it. In this situation, I usually squash all the commits during the rebase to resolve all conflicts at once.
The problem is that I'm no longer able to use "git range-diff" after such a rebase. On one side, I have N commits and on the other, I have a single commit which is the result of squashing N commits. "git range-diff" won't let me compare such histories because it wants to match commits one by one.
There are several workarounds to this situation.
The first one is to squash all the commits before rebasing. This works because I now have a single commit on both sides. I must say I don't really like this solution because it requires creating extra git objects needlessly.
Another one is to run "a diff of diffs" manually by running multiple git commands successively. This is the approach I have chosen and that I have been using for more than a year now. I basically dump the two diffs into two files on disk, then run "git diff --no-index" to compare those diffs and finally reimplement dual coloring by hand to display it in the terminal using less. This works surprisingly well and is usually very close to what "git range-diff" would itself output. I shared my NodeJS script which does exactly that on StackOverflow if you're interested in the details: https://stackoverflow.com/questions/70416396/how-to-pretty-format-an-arbitrary-diff-of-diffs
What I like about this is that, first, I don't pollute my repository with git objects that I will never use again, but more importantly, it's very versatile. I can specify the number of commits that I want on each side, and I will get my range-diff between my two arbitrary histories.
This is a quite different strategy from what "git range-diff" offers today. While matching the commits one by one is certainly useful in many contexts, I highly appreciate being able to opt out of that and switch to a patch-based range-diff when I need it.
This is so useful to me that I'm wondering why "git range-diff" does not implement this behavior. We could imagine a flag that would make it behave as I described. Is this something that was ever considered? Are there any technical difficulties that I'm completely missing? Do you think this could be helpful to other people?
I think it would be really nice to see this in git natively, hence my message. But if that is not feasible, I will still be happy to have my script!
Thank you for reading my lengthy message and I'm looking forward to reading your insights on the matter!
Best regards,
Robin DOS ANJOS
^ permalink raw reply
* [PATCH 1/1] attr: enable attr pathspec magic for git-add and git-stash
From: Joanna Wang @ 2023-11-02 17:53 UTC (permalink / raw)
To: gitster; +Cc: git, jojwang
In-Reply-To: <xmqqfs1ooil2.fsf@gitster.g>
This lets users limit files or exclude files based on file
attributes during git-add and git-stash.
For example, the chromium project would like to use this like
"git add --all ':(exclude,attr:submodule)'", as submodules are managed in a
unique way and often results in submodule changes that users do not want in
their commits.
This does not change any attr magic implementation. It is only adding
attr as an allowed pathspec in git-add and git-stash, which was previously
blocked by GUARD_PATHSPEC and a pathspec mask in parse_pathspec()).
However, this does fix a bug in prefix_magic() where attr values were unintentionally removed.
This was hit whenever parse_pathspec() is called with PATHSPEC_PREFIX_ORIGIN as a flag,
which was the case for git-stash. More details here:
https://lore.kernel.org/git/CAMmZTi-0QKtj7Q=sbC5qhipGsQxJFOY-Qkk1jfkRYwfF5FcUVg@mail.gmail.com/
It is possible that when the attr pathspec feature was first added in
b0db704652 (pathspec: allow querying for attributes, 2017-03-13),
"PATHSPEC_ATTR" was just unintentionally left out of a few GUARD_PATHSPEC() invocations.
Later, to get a more user-friendly error message when attr was used with git-add,
PATHSPEC_ATTR was added as a mask to git-add's invocation of parse_pathspec()
84d938b732 (add: do not accept pathspec magic 'attr', 2018-09-18).
However, this user-friendly error message was never added for git-stash.
Signed-off-by: Joanna Wang <jojwang@google.com>
---
> Indeed, if you are going to pass the original "elt" string *anyway*,
> you have all the info in there that you need. I wonder if it makes
> sense to get rid of the "unsigned magic" bitset from the parameter,
This was my initial strategy but ran into trouble when the magic was
in shorthand form. Upon closer look at how the shorthand works
(e.g. shorthand and longhand can never mix so
':!/(attr:chicken)file' would make <(attr:chicken)file> the match string)
I tried this again by processing the forms separately.
It would still need both the element and element_magic, but I think it
addresses the concerns with future changes where multiple magic match
values could be allowed and the match values could be any string. These
changes would be fine as long as there is no overlap between magic that
takes a user-supplied value and magic that can be expressed in shorthand.
builtin/add.c | 7 ++-
dir.c | 3 +-
pathspec.c | 25 +++++---
t/t6135-pathspec-with-attrs.sh | 108 +++++++++++++++++++++++++++++++--
4 files changed, 125 insertions(+), 18 deletions(-)
diff --git a/builtin/add.c b/builtin/add.c
index 5126d2ede3..d46e4d10e9 100644
--- a/builtin/add.c
+++ b/builtin/add.c
@@ -424,7 +424,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)
* Check the "pathspec '%s' did not match any files" block
* below before enabling new magic.
*/
- parse_pathspec(&pathspec, PATHSPEC_ATTR,
+ parse_pathspec(&pathspec, 0,
PATHSPEC_PREFER_FULL |
PATHSPEC_SYMLINK_LEADING_PATH,
prefix, argv);
@@ -433,7 +433,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)
if (pathspec.nr)
die(_("'%s' and pathspec arguments cannot be used together"), "--pathspec-from-file");
- parse_pathspec_file(&pathspec, PATHSPEC_ATTR,
+ parse_pathspec_file(&pathspec, 0,
PATHSPEC_PREFER_FULL |
PATHSPEC_SYMLINK_LEADING_PATH,
prefix, pathspec_from_file, pathspec_file_nul);
@@ -504,7 +504,8 @@ int cmd_add(int argc, const char **argv, const char *prefix)
PATHSPEC_LITERAL |
PATHSPEC_GLOB |
PATHSPEC_ICASE |
- PATHSPEC_EXCLUDE);
+ PATHSPEC_EXCLUDE |
+ PATHSPEC_ATTR);
for (i = 0; i < pathspec.nr; i++) {
const char *path = pathspec.items[i].match;
diff --git a/dir.c b/dir.c
index 16fdb03f2a..4d1cd039be 100644
--- a/dir.c
+++ b/dir.c
@@ -2179,7 +2179,8 @@ static int exclude_matches_pathspec(const char *path, int pathlen,
PATHSPEC_LITERAL |
PATHSPEC_GLOB |
PATHSPEC_ICASE |
- PATHSPEC_EXCLUDE);
+ PATHSPEC_EXCLUDE |
+ PATHSPEC_ATTR);
for (i = 0; i < pathspec->nr; i++) {
const struct pathspec_item *item = &pathspec->items[i];
diff --git a/pathspec.c b/pathspec.c
index bb1efe1f39..588a2cde4d 100644
--- a/pathspec.c
+++ b/pathspec.c
@@ -109,16 +109,23 @@ static struct pathspec_magic {
{ PATHSPEC_ATTR, '\0', "attr" },
};
-static void prefix_magic(struct strbuf *sb, int prefixlen, unsigned magic)
+static void prefix_magic(struct strbuf *sb, int prefixlen, unsigned magic, const char *element)
{
- int i;
- strbuf_addstr(sb, ":(");
- for (i = 0; i < ARRAY_SIZE(pathspec_magic); i++)
- if (magic & pathspec_magic[i].bit) {
- if (sb->buf[sb->len - 1] != '(')
- strbuf_addch(sb, ',');
- strbuf_addstr(sb, pathspec_magic[i].name);
+ if (element[1] != '(') {
+ /* Process an element in shorthand form (e.g. ":!/<match>") */
+ strbuf_addstr(sb, ":(");
+ for (int i = 0; i < ARRAY_SIZE(pathspec_magic); i++) {
+ if ((magic & pathspec_magic[i].bit) && (pathspec_magic[i].mnemonic != '\0')) {
+ if (sb->buf[sb->len - 1] != '(')
+ strbuf_addch(sb, ',');
+ strbuf_addstr(sb, pathspec_magic[i].name);
+ }
}
+ } else {
+ /* For an element in longhand form, we simply copy everything up to the final ')' */
+ int len = strchr(element, ')') - element;
+ strbuf_add(sb, element, len);
+ }
strbuf_addf(sb, ",prefix:%d)", prefixlen);
}
@@ -493,7 +500,7 @@ static void init_pathspec_item(struct pathspec_item *item, unsigned flags,
struct strbuf sb = STRBUF_INIT;
/* Preserve the actual prefix length of each pattern */
- prefix_magic(&sb, prefixlen, element_magic);
+ prefix_magic(&sb, prefixlen, element_magic, elt);
strbuf_addstr(&sb, match);
item->original = strbuf_detach(&sb, NULL);
diff --git a/t/t6135-pathspec-with-attrs.sh b/t/t6135-pathspec-with-attrs.sh
index f70c395e75..e46fa176ed 100755
--- a/t/t6135-pathspec-with-attrs.sh
+++ b/t/t6135-pathspec-with-attrs.sh
@@ -64,12 +64,24 @@ test_expect_success 'setup .gitattributes' '
fileSetLabel label
fileValue label=foo
fileWrongLabel label☺
+ newFileA* labelA
+ newFileB* labelB
EOF
echo fileSetLabel label1 >sub/.gitattributes &&
git add .gitattributes sub/.gitattributes &&
git commit -m "add attributes"
'
+test_expect_success 'setup .gitignore' '
+ cat <<-\EOF >.gitignore &&
+ actual
+ expect
+ pathspec_file
+ EOF
+ git add .gitignore &&
+ git commit -m "add gitignore"
+'
+
test_expect_success 'check specific set attr' '
cat <<-\EOF >expect &&
fileSetLabel
@@ -150,6 +162,7 @@ test_expect_success 'check specific value attr (2)' '
test_expect_success 'check unspecified attr' '
cat <<-\EOF >expect &&
.gitattributes
+ .gitignore
fileA
fileAB
fileAC
@@ -175,6 +188,7 @@ test_expect_success 'check unspecified attr' '
test_expect_success 'check unspecified attr (2)' '
cat <<-\EOF >expect &&
HEAD:.gitattributes
+ HEAD:.gitignore
HEAD:fileA
HEAD:fileAB
HEAD:fileAC
@@ -200,6 +214,7 @@ test_expect_success 'check unspecified attr (2)' '
test_expect_success 'check multiple unspecified attr' '
cat <<-\EOF >expect &&
.gitattributes
+ .gitignore
fileC
fileNoLabel
fileWrongLabel
@@ -239,16 +254,99 @@ test_expect_success 'fail on multiple attr specifiers in one pathspec item' '
test_i18ngrep "Only one" actual
'
-test_expect_success 'fail if attr magic is used places not implemented' '
+test_expect_success 'fail if attr magic is used in places not implemented' '
# The main purpose of this test is to check that we actually fail
# when you attempt to use attr magic in commands that do not implement
- # attr magic. This test does not advocate git-add to stay that way,
- # though, but git-add is convenient as it has its own internal pathspec
- # parsing.
- test_must_fail git add ":(attr:labelB)" 2>actual &&
+ # attr magic. This test does not advocate check-ignore to stay that way.
+ # When you teach the command to grok the pathspec, you need to find
+ # another command to replace it for the test.
+ test_must_fail git check-ignore ":(attr:labelB)" 2>actual &&
test_i18ngrep "magic not supported" actual
'
+test_expect_success 'check that attr magic works for git stash push' '
+ cat <<-\EOF >expect &&
+ A sub/newFileA-foo
+ EOF
+ >sub/newFileA-foo &&
+ >sub/newFileB-foo &&
+ git stash push --include-untracked -- ":(exclude,attr:labelB)" &&
+ git stash show --include-untracked --name-status >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'check that attr magic works for git add --all' '
+ cat <<-\EOF >expect &&
+ sub/newFileA-foo
+ EOF
+ >sub/newFileA-foo &&
+ >sub/newFileB-foo &&
+ git add --all ":(exclude,attr:labelB)" &&
+ git diff --name-only --cached >actual &&
+ git restore -W -S . &&
+ test_cmp expect actual
+'
+
+test_expect_success 'check that attr magic works for git add -u' '
+ cat <<-\EOF >expect &&
+ sub/fileA
+ EOF
+ >sub/newFileA-foo &&
+ >sub/newFileB-foo &&
+ >sub/fileA &&
+ >sub/fileB &&
+ git add -u ":(exclude,attr:labelB)" &&
+ git diff --name-only --cached >actual &&
+ git restore -S -W . && rm sub/new* &&
+ test_cmp expect actual
+'
+
+test_expect_success 'check that attr magic works for git add <path>' '
+ cat <<-\EOF >expect &&
+ fileA
+ fileB
+ sub/fileA
+ EOF
+ >fileA &&
+ >fileB &&
+ >sub/fileA &&
+ >sub/fileB &&
+ git add ":(exclude,attr:labelB)sub/*" &&
+ git diff --name-only --cached >actual &&
+ git restore -S -W . &&
+ test_cmp expect actual
+'
+
+test_expect_success 'check that attr magic works for git -add .' '
+ cat <<-\EOF >expect &&
+ sub/fileA
+ EOF
+ >fileA &&
+ >fileB &&
+ >sub/fileA &&
+ >sub/fileB &&
+ cd sub &&
+ git add . ":(exclude,attr:labelB)" &&
+ cd .. &&
+ git diff --name-only --cached >actual &&
+ git restore -S -W . &&
+ test_cmp expect actual
+'
+
+test_expect_success 'check that attr magic works for git add --pathspec-from-file' '
+ cat <<-\EOF >pathspec_file &&
+ :(exclude,attr:labelB)
+ EOF
+ cat <<-\EOF >expect &&
+ sub/newFileA-foo
+ EOF
+ >sub/newFileA-foo &&
+ >sub/newFileB-foo &&
+ git add --all --pathspec-from-file=pathspec_file &&
+ git diff --name-only --cached >actual &&
+ test_cmp expect actual
+'
+
test_expect_success 'abort on giving invalid label on the command line' '
test_must_fail git ls-files . ":(attr:☺)"
'
--
2.42.0.869.gea05f2083d-goog
^ permalink raw reply related
* [ANNOUNCE] Git v2.43.0-rc0
From: Junio C Hamano @ 2023-11-02 17:36 UTC (permalink / raw)
To: git; +Cc: Linux Kernel, git-packagers
An early preview release Git v2.43.0-rc0 is now available for
testing at the usual places. It is comprised of 399 non-merge
commits since v2.42.0, contributed by 61 people, 16 of which are
new faces [*].
The tarballs are found at:
https://www.kernel.org/pub/software/scm/git/testing/
The following public repositories all have a copy of the
'v2.43.0-rc0' tag and the 'master' branch that the tag points at:
url = https://git.kernel.org/pub/scm/git/git
url = https://kernel.googlesource.com/pub/scm/git/git
url = git://repo.or.cz/alt-git.git
url = https://github.com/gitster/git
New contributors whose contributions weren't in v2.42.0 are as follows.
Welcome to the Git development community!
Alyssa Ross, Caleb Hill, Dorcas AnonoLitunya, Dragan Simic,
Isoken June Ibizugbe, Jan Alexander Steffens (heftig), Javier
Mora, ks1322 ks1322, Mark Ruvald Pedersen, Matthew McClain,
Naomi Ibe, Romain Chossart, Tang Yuyi, Vipul Kumar, 王常新,
and 谢致邦 (XIE Zhibang).
Returning contributors who helped this release are as follows.
Thanks for your continued support.
Ævar Arnfjörð Bjarmason, Andy Koppe, Bagas Sanjaya,
Beat Bolli, brian m. carlson, Calvin Wan, Christian Couder,
Christian Hesse, Derrick Stolee, Drew DeVault, Elijah Newren,
Eric W. Biederman, Eric Wong, Evan Gates, Han Young, Hariom
Verma, Jacob Abel, Jason Hatton, Jeff King, Johannes Schindelin,
John Cai, Josh Soref, Josip Sokcevic, Junio C Hamano, Kousik
Sanagavarapu, Kristoffer Haugsbakk, Linus Arver, Mark Levedahl,
Martin Storsjö, M Hickford, Michal Suchanek, Oswald Buddenhagen,
Patrick Steinhardt, Philippe Blain, Phillip Wood, René Scharfe,
Rubén Justo, Sergey Organov, Shuqi Liang, Stefan Haller,
Štěpán Němec, Taylor Blau, Teng Long, Victoria Dye, and
Wesley Schwengle.
[*] We are counting not just the authorship contribution but issue
reporting, mentoring, helping and reviewing that are recorded in
the commit trailers.
----------------------------------------------------------------
Git v2.43 Release Notes (draft)
===============================
Backward Compatibility Notes
* The "--rfc" option of "git format-patch" used to be a valid way to
override an earlier "--subject-prefix=<something>" on the command
line and replace it with "[RFC PATCH]", but from this release, it
merely prefixes the string "RFC " in front of the given subject
prefix. If you are negatively affected by this change, please use
"--subject-prefix=PATCH --rfc" as a replacement.
* "git rev-list --stdin" learned to take non-revisions (like "--not")
recently from the standard input, but the way such a "--not" was
handled was quite confusing, which has been rethought. The updated
rule is that "--not" given from the command line only affects revs
given from the command line that comes but not revs read from the
standard input, and "--not" read from the standard input affects
revs given from the stanrdard input and not revs given from the
command line.
UI, Workflows & Features
* A message written in olden time prevented a branch from getting
checked out saying it is already checked out elsewhere, but these
days, we treat a branch that is being bisected or rebased just like
a branch that is checked out and protect it. Rephrase the message
to say that the branch is in use.
* Hourly and other schedule of "git maintenance" jobs are randomly
distributed now.
* "git cmd -h" learned to signal which options can be negated by
listing such options like "--[no-]opt".
* The way authentication related data other than passwords (e.g.
oath token and password expiration data) are stored in libsecret
keyrings has been rethought.
* Update two credential helpers to correctly match which credential
to erase; they dropped not the ones with stale password.
* Git GUI updates.
* "git format-patch" learns a way to feed cover letter description,
that (1) can be used on detached HEAD where there is no branch
description available, and (2) also can override the branch
description if there is one.
* Use of --max-pack-size to allow multiple packfiles to be created is
now supported even when we are sending unreachable objects to cruft
packs.
* "git format-patch --rfc --subject-prefix=<foo>" used to ignore the
"--subject-prefix" option and used "[RFC PATCH]"; now we will add
"RFC" prefix to whatever subject prefix is specified.
* "git log --format" has been taught the %(decorate) placeholder.
* The default log message created by "git revert", when reverting a
commit that records a revert, has been tweaked, to encourage people
describe complex "revert of revert of revert" situation better in
their own words.
* The command-line complation support (in contrib/) learned to
complete "git commit --trailer=" for possible trailer keys.
* "git update-index" learns "--show-index-version" to inspect
the index format version used by the on-disk index file.
* "git diff" learned diff.statNameWidth configuration variable, to
give the default width for the name part in the "--stat" output.
* "git range-diff --notes=foo" compared "log --notes=foo --notes" of
the two ranges, instead of using just the specified notes tree.
* The command line completion script (in contrib/) can be told to
complete aliases by including ": git <cmd> ;" in the alias to tell
it that the alias should be completed similar to how "git <cmd>" is
completed. The parsing code for the alias as been loosened to
allow ';' without an extra space before it.
* "git for-each-ref" and friends learned to apply mailmap to
authorname and other fields.
* "git repack" machinery learns to pay attention to the "--filter="
option.
* "git repack" learned "--max-cruft-size" to prevent cruft packs from
growing without bounds.
* "git merge-tree" learned to take strategy backend specific options
via the "-X" option, like "git merge" does.
* "git log" and friends learned "--dd" that is a short-hand for
"--diff-merges=first-parent -p".
* The attribute subsystem learned to honor `attr.tree` configuration
that specifies which tree to read the .gitattributes files from.
Performance, Internal Implementation, Development Support etc.
* "git check-attr" has been taught to work better with sparse-index.
* It may be tempting to leave the help text NULL for a command line
option that is either hidden or too obvious, but "git subcmd -h"
and "git subcmd --help-all" would have segfaulted if done so. Now
the help text is optional.
* Tests that are known to pass with LSan are now marked as such.
(merge 5fafe8c95f tb/mark-more-tests-as-leak-free later to maint).
* Flaky "git p4" tests, as well as "git svn" tests, are now skipped
in the (rather expensive) sanitizer CI job.
(merge 6ba913629f js/ci-san-skip-p4-and-svn-tests later to maint).
* Tests with LSan from time to time seem to emit harmless message
that makes our tests unnecessarily flaky; we work it around by
filtering the uninteresting output.
(merge 370ef7e40d jk/test-lsan-denoise-output later to maint).
* Unused parameters to functions are marked as such, and/or removed,
in order to bring us closer to -Wunused-parameter clean.
* The code to keep track of existing packs in the repository while
repacking has been refactored.
* The "streaming" interface used for bulk-checkin codepath has been
narrowed to take only blob objects for now, with no real loss of
functionality.
* GitHub CI workflow has learned to trigger Coverity check.
(merge 3349520e1a js/ci-coverity later to maint).
* Test coverage for trailers has been improved.
* The code to iterate over loose references have been optimized to
reduce the number of lstat() system calls.
(merge 2cdb796101 vd/loose-ref-iteration-optimization later to maint).
* The codepaths that read "chunk" formatted files have been corrected
to pay attention to the chunk size and notice broken files.
Fixes since v2.42
-----------------
* Overly long label names used in the sequencer machinery are now
chopped to fit under filesystem limitation.
(merge ac300bda10 mp/rebase-label-length-limit later to maint).
* Scalar updates.
(merge f9a547d3a7 ds/scalar-updates later to maint).
* Tweak GitHub Actions CI so that pushing the same commit to multiple
branch tips at the same time will not waste building and testing
the same thing twice.
(merge 99fe06cbfd jc/ci-skip-same-commit later to maint).
* The commit-graph verification code that detects mixture of zero and
non-zero generation numbers has been updated.
(merge db6044d762 tb/commit-graph-verify-fix later to maint).
* "git diff -w --exit-code" with various options did not work
correctly, which is being addressed.
(merge a64f8b2595 jc/diff-exit-code-with-w-fixes later to maint).
* transfer.unpackLimit ought to be used as a fallback, but overrode
fetch.unpackLimit and receive.unpackLimit instead.
(merge f3d33f8cfe ts/unpacklimit-config-fix later to maint).
* The use of API between two calls to require_clean_work_tree() from
the sequencer code has been cleaned up for consistency.
(merge a9b5955e07 ob/sequencer-empty-hint-fix later to maint).
* "git diff --no-such-option" and other corner cases around the exit
status of the "diff" command has been corrected.
(merge 5cc6b2d70b jk/diff-result-code-cleanup later to maint).
* "git for-each-ref --sort='contents:size'" sorts the refs according
to size numerically, giving a ref that points at a blob twelve-byte
(12) long before showing a blob hundred-byte (100) long.
(merge 6d79cd8474 ks/ref-filter-sort-numerically later to maint).
* We now limit depth of the tree objects and maximum length of
pathnames recorded in tree objects.
(merge 4d5693ba05 jk/tree-name-and-depth-limit later to maint).
* Various fixes to the behavior of "rebase -i" when the command got
interrupted by conflicting changes.
(merge 203573b024 pw/rebase-i-after-failure later to maint).
* References from description of the `--patch` option in various
manual pages have been simplified and improved.
(merge 11422f23e3 so/diff-doc-for-patch-update later to maint).
* "git grep -e A --no-or -e B" is accepted, even though the negation
of "or" did not mean anything, which has been tightened.
(merge aae8558b10 rs/grep-no-no-or later to maint).
* The completion script (in contrib/) has been taught to treat the
"-t" option to "git checkout" and "git switch" just like the
"--track" option, to complete remote-tracking branches.
(merge 9f892830d6 js/complete-checkout-t later to maint).
* "git diff --no-index -R <(one) <(two)" did not work correctly,
which has been corrected.
(merge 48944f214c pw/diff-no-index-from-named-pipes later to maint).
* Update "git maintenance" timers' implementation based on systemd
timers to work with WSL.
(merge 5e8515e8e8 js/systemd-timers-wsl-fix later to maint).
* "git diff --cached" codepath did not fill the necessary stat
information for a file when fsmonitor knows it is clean and ended
up behaving as if it is not clean, which has been corrected.
(merge 6a044a2048 js/diff-cached-fsmonitor-fix later to maint).
* Clarify how "alias.foo = : git cmd ; aliased-command-string" should
be spelled with necessary whitespaces around punctuation marks to
work.
(merge 4333267995 pb/completion-aliases-doc later to maint).
* HTTP Header redaction code has been adjusted for a newer version of
cURL library that shows its traces differently from earlier
versions.
(merge 0763c3a2c4 jk/redact-h2h3-headers-fix later to maint).
* An error message given by "git send-email" when given a malformed
address did not give correct information, which has been corrected.
(merge 12288cc44e tb/send-email-extract-valid-address-error-message-fix later to maint).
* UBSan options were not propagated through the test framework to git
run via the httpd, unlike ASan options, which has been corrected.
(merge 252d693797 jk/test-pass-ubsan-options-to-http-test later to maint).
* "checkout --merge -- path" and "update-index --unresolve path" did
not resurrect conflicted state that was resolved to remove path,
but now they do.
(merge 5bdedac3c7 jc/unresolve-removal later to maint).
* The display width table for unicode characters has been updated for
Unicode 15.1
(merge 872976c37e bb/unicode-width-table-15 later to maint).
* Update mailmap entry for Derrick.
(merge 6e5457d8c7 ds/mailmap-entry-update later to maint).
* In .gitmodules files, submodules are keyed by their names, and the
path to the submodule whose name is $name is specified by the
submodule.$name.path variable. There were a few codepaths that
mixed the name and path up when consulting the submodule database,
which have been corrected. It took long for these bugs to be found
as the name of a submodule initially is the same as its path, and
the problem does not surface until it is moved to a different path,
which apparently happens very rarely.
* "git diff --merge-base X other args..." insisted that X must be a
commit and errored out when given an annotated tag that peels to a
commit, but we only need it to be a committish. This has been
corrected.
(merge 4adceb5a29 ar/diff-index-merge-base-fix later to maint).
* Fix "git merge-tree" to stop segfaulting when the --attr-source
option is used.
(merge e95bafc52f jc/merge-ort-attr-index-fix later to maint).
* Unlike "git log --pretty=%D", "git log --pretty="%(decorate)" did
not auto-initialize the decoration subsystem, which has been
corrected.
* Feeding "git stash store" with a random commit that was not created
by "git stash create" now errors out.
(merge d9b6634589 jc/fail-stash-to-store-non-stash later to maint).
* The index file has room only for lower 32-bit of the file size in
the cached stat information, which means cached stat information
will have 0 in its sd_size member for a file whose size is multiple
of 4GiB. This is mistaken for a racily clean path. Avoid it by
storing a bogus sd_size value instead for such files.
(merge 5143ac07b1 bc/racy-4gb-files later to maint).
* "git p4" tried to store symlinks to LFS when told, but has been
fixed not to do so, because it does not make sense.
(merge 10c89a02b0 mm/p4-symlink-with-lfs later to maint).
* The codepath to handle recipient addresses `git send-email
--compose` learns from the user was completely broken, which has
been corrected.
(merge 3ec6167567 jk/send-email-fix-addresses-from-composed-messages later to maint).
* Other code cleanup, docfix, build fix, etc.
(merge fd3ba590d8 ws/git-push-doc-grammofix later to maint).
(merge 5f33a843de ds/upload-pack-error-sequence-fix later to maint).
(merge beaa1d952b jk/function-pointer-mismatches-fix later to maint).
(merge b46d806ea5 ob/t9001-indent-fix later to maint).
(merge fdc9914c28 ja/worktree-orphan later to maint).
(merge c2cbefc510 jc/mv-d-to-d-error-message-fix later to maint).
(merge d0fc552bfc ch/t6300-verify-commit-test-cleanup later to maint).
(merge aa4b83dd5e ws/git-svn-retire-faketerm later to maint).
(merge edf80d23f1 jk/ci-retire-allow-ref later to maint).
(merge 256a94ef6c bc/more-git-var later to maint).
(merge 82af2c639c ob/sequencer-reword-error-message later to maint).
(merge 2a63c79dae rs/grep-parseopt-simplify later to maint).
(merge 078c42531e rs/name-rev-use-opt-hidden-bool later to maint).
(merge 63642d58b4 ob/sequencer-remove-dead-code later to maint).
(merge 8aae489756 ob/t3404-typofix later to maint).
(merge 58be11432e eg/config-type-path-docfix later to maint).
(merge 563f339d98 ch/clean-docfix later to maint).
(merge 4fbe83fcd9 hy/doc-show-is-like-log-not-diff-tree later to maint).
(merge 43abaaf008 ob/am-msgfix later to maint).
(merge c2c349a15c xz/commit-title-soft-limit-doc later to maint).
(merge f4cbb32c27 rs/parse-opt-ctx-cleanup later to maint).
(merge badf2fe1c3 jk/decoration-and-other-leak-fixes later to maint).
(merge cebfaaa333 sn/cat-file-doc-update later to maint).
(merge 8b3aa36f5a ps/rewritten-is-per-worktree-doc later to maint).
(merge ffbf6a748d jc/update-list-references-to-lore later to maint).
(merge 14d569b1a7 jc/am-doc-whitespace-action-fix later to maint).
(merge 48399e9cf0 ni/die-message-fix-for-git-add later to maint).
(merge ca3285dd69 ps/git-repack-doc-fixes later to maint).
(merge 243c79fdc7 wx/merge-ort-comment-typofix later to maint).
(merge a060705d94 jc/commit-new-underscore-index-fix later to maint).
(merge f6d83e2115 ms/doc-push-fix later to maint).
----------------------------------------------------------------
Changes since v2.42.0 are as follows:
Alyssa Ross (1):
diff: fix --merge-base with annotated tags
Andy Koppe (8):
pretty-formats: enclose options in angle brackets
decorate: refactor format_decorations()
decorate: avoid some unnecessary color overhead
decorate: color each token separately
pretty: add %(decorate[:<options>]) format
pretty: add pointer and tag options to %(decorate)
decorate: use commit color for HEAD arrow
pretty: fix ref filtering for %(decorate) formats
Beat Bolli (1):
unicode: update the width tables to Unicode 15.1
Caleb Hill (1):
git-clean doc: fix "without do cleaning" typo
Calvin Wan (4):
hex-ll: separate out non-hash-algo functions
wrapper: reduce scope of remove_or_warn()
config: correct bad boolean env value error message
parse: separate out parsing functions from config.h
Christian Couder (9):
pack-objects: allow `--filter` without `--stdout`
t/helper: add 'find-pack' test-tool
repack: refactor finishing pack-objects command
repack: refactor finding pack prefix
pack-bitmap-write: rebuild using new bitmap when remapping
repack: add `--filter=<filter-spec>` option
gc: add `gc.repackFilter` config option
repack: implement `--filter-to` for storing filtered out objects
gc: add `gc.repackFilterTo` config option
Christian Hesse (2):
t/lib-gpg: forcibly run a trustdb update
t/t6300: drop magic filtering
Derrick Stolee (13):
upload-pack: fix race condition in error messages
maintenance: add get_random_minute()
maintenance: use random minute in launchctl scheduler
maintenance: use random minute in Windows scheduler
maintenance: use random minute in cron scheduler
maintenance: swap method locations
maintenance: use random minute in systemd scheduler
maintenance: fix systemd schedule overlaps
maintenance: update schedule before config
scalar: add --[no-]src option
setup: add discover_git_directory_reason()
scalar reconfigure: help users remove buggy repos
mailmap: change primary address for Derrick Stolee
Dorcas AnonoLitunya (1):
t7601: use "test_path_is_file" etc. instead of "test -f"
Dragan Simic (2):
diff --stat: add config option to limit filename width
diff --stat: set the width defaults in a helper function
Drew DeVault (1):
format-patch: --rfc honors what --subject-prefix sets
Elijah Newren (25):
documentation: wording improvements
documentation: fix small error
documentation: fix typos
documentation: fix apostrophe usage
documentation: add missing words
documentation: remove extraneous words
documentation: fix subject/verb agreement
documentation: employ consistent verb tense for a list
documentation: fix verb tense
documentation: fix adjective vs. noun
documentation: fix verb vs. noun
documentation: fix singular vs. plural
documentation: whitespace is already generally plural
documentation: fix choice of article
documentation: add missing article
documentation: remove unnecessary hyphens
documentation: add missing hyphens
documentation: use clearer prepositions
documentation: fix punctuation
documentation: fix capitalization
documentation: fix whitespace issues
documentation: add some commas where they are helpful
documentation: add missing fullstops
documentation: add missing quotes
documentation: add missing parenthesis
Eric W. Biederman (1):
bulk-checkin: only support blobs in index_bulk_checkin
Eric Wong (1):
treewide: fix various bugs w/ OpenSSL 3+ EVP API
Evan Gates (1):
git-config: fix misworded --type=path explanation
Han Young (1):
show doc: redirect user to git log manual instead of git diff-tree
Isoken June Ibizugbe (1):
builtin/branch.c: adjust error messages to coding guidelines
Jacob Abel (1):
builtin/worktree.c: fix typo in "forgot fetch" msg
Jan Alexander Steffens (heftig) (6):
submodule--helper: use submodule_from_path in set-{url,branch}
submodule--helper: return error from set-url when modifying failed
t7419: actually test the branch switching
t7419, t7420: use test_cmp_config instead of grepping .gitmodules
t7419: test that we correctly handle renamed submodules
t7420: test that we correctly handle renamed submodules
Jason Hatton (1):
Prevent git from rehashing 4GiB files
Javier Mora (2):
git-status.txt: fix minor asciidoc format issue
doc/git-bisect: clarify `git bisect run` syntax
Jeff King (113):
hashmap: use expected signatures for comparison functions
diff-files: avoid negative exit value
diff: show usage for unknown builtin_diff_files() options
diff: die when failing to read index in git-diff builtin
diff: drop useless return from run_diff_{files,index} functions
diff: drop useless return values in git-diff helpers
diff: drop useless "status" parameter from diff_result_code()
commit-graph: verify swapped zero/non-zero generation cases
test-lib: ignore uninteresting LSan output
sequencer: use repository parameter in short_commit_name()
sequencer: mark repository argument as unused
ref-filter: mark unused parameters in parser callbacks
pack-bitmap: mark unused parameters in show_object callback
worktree: mark unused parameters in each_ref_fn callback
commit-graph: mark unused data parameters in generation callbacks
ls-tree: mark unused parameter in callback
stash: mark unused parameter in diff callback
trace2: mark unused us_elapsed_absolute parameters
trace2: mark unused config callback parameter
test-trace2: mark unused argv/argc parameters
grep: mark unused parameter in output function
add-interactive: mark unused callback parameters
negotiator/noop: mark unused callback parameters
worktree: mark unused parameters in noop repair callback
imap-send: mark unused parameters with NO_OPENSSL
grep: mark unused parmaeters in pcre fallbacks
credential: mark unused parameter in urlmatch callback
fetch: mark unused parameter in ref_transaction callback
bundle-uri: mark unused parameters in callbacks
gc: mark unused descriptors in scheduler callbacks
update-ref: mark unused parameter in parser callbacks
ci: allow branch selection through "vars"
ci: deprecate ci/config/allow-ref script
merge: make xopts a strvec
merge: simplify parsing of "-n" option
format-patch: use OPT_STRING_LIST for to/cc options
tree-walk: reduce stack size for recursive functions
tree-walk: drop MAX_TRAVERSE_TREES macro
tree-walk: rename "error" variable
fsck: detect very large tree pathnames
add core.maxTreeDepth config
traverse_trees(): respect max_allowed_tree_depth
read_tree(): respect max_allowed_tree_depth
list-objects: respect max_allowed_tree_depth
tree-diff: respect max_allowed_tree_depth
lower core.maxTreeDepth default to 2048
checkout-index: delay automatic setting of to_tempfile
parse-options: prefer opt->value to globals in callbacks
parse-options: mark unused "opt" parameter in callbacks
merge: do not pass unused opt->value parameter
parse-options: add more BUG_ON() annotations
interpret-trailers: mark unused "unset" parameters in option callbacks
parse-options: mark unused parameters in noop callback
merge-ort: drop custom err() function
merge-ort: stop passing "opt" to read_oid_strbuf()
merge-ort: drop unused parameters from detect_and_process_renames()
merge-ort: drop unused "opt" parameter from merge_check_renames_reusable()
http: factor out matching of curl http/2 trace lines
http: update curl http/2 info matching for curl 8.3.0
merge-ort: lowercase a few error messages
fsmonitor: prefer repo_git_path() to git_pathdup()
fsmonitor/win32: drop unused parameters
fsmonitor: mark some maybe-unused parameters
fsmonitor/win32: mark unused parameter in fsm_os__incompatible()
fsmonitor: mark unused parameters in stub functions
fsmonitor/darwin: mark unused parameters in system callback
fsmonitor: mark unused hashmap callback parameters
run-command: mark unused parameters in start_bg_wait callbacks
test-lib: set UBSAN_OPTIONS to match ASan
commit-graph: factor out chain opening function
commit-graph: check mixed generation validation when loading chain file
t5324: harmonize sha1/sha256 graph chain corruption
commit-graph: detect read errors when verifying graph chain
commit-graph: tighten chain size check
commit-graph: report incomplete chains during verification
t6700: mark test as leak-free
commit-reach: free temporary list in get_octopus_merge_bases()
merge: free result of repo_get_merge_bases()
commit-graph: move slab-clearing to close_commit_graph()
commit-graph: free all elements of graph chain
commit-graph: delay base_graph assignment in add_graph_to_chain()
commit-graph: free graph struct that was not added to chain
commit-graph: free write-context entries before overwriting
commit-graph: free write-context base_graph_name during cleanup
commit-graph: clear oidset after finishing write
decorate: add clear_decoration() function
revision: clear decoration structs during release_revisions()
daemon: free listen_addr before returning
repack: free existing_cruft array after use
chunk-format: note that pair_chunk() is unsafe
t: add library for munging chunk-format files
midx: stop ignoring malformed oid fanout chunk
commit-graph: check size of oid fanout chunk
midx: check size of oid lookup chunk
commit-graph: check consistency of fanout table
midx: check size of pack names chunk
midx: enforce chunk alignment on reading
midx: check size of object offset chunk
midx: bounds-check large offset chunk
midx: check size of revindex chunk
commit-graph: check size of commit data chunk
commit-graph: detect out-of-bounds extra-edges pointers
commit-graph: bounds-check base graphs chunk
commit-graph: check size of generations chunk
commit-graph: bounds-check generation overflow chunk
commit-graph: check bounds when accessing BDAT chunk
commit-graph: check bounds when accessing BIDX chunk
commit-graph: detect out-of-order BIDX offsets
chunk-format: drop pair_chunk_unsafe()
t5319: make corrupted large-offset test more robust
doc/send-email: mention handling of "reply-to" with --compose
Revert "send-email: extract email-parsing code into a subroutine"
send-email: handle to/cc/bcc from --compose message
Johannes Schindelin (17):
windows: ignore empty `PATH` elements
is_Cygwin: avoid `exec`ing anything
Move is_<platform> functions to the beginning
Move the `_which` function (almost) to the top
Work around Tcl's default `PATH` lookup
rebase: allow overriding the maximal length of the generated labels
ci: avoid building from the same commit in parallel
ci(linux-asan-ubsan): let's save some time
var: avoid a segmentation fault when `HOME` is unset
completion(switch/checkout): treat --track and -t the same
maintenance(systemd): support the Windows Subsystem for Linux
ci: add a GitHub workflow to submit Coverity scans
coverity: cache the Coverity Build Tool
coverity: allow overriding the Coverity project
coverity: support building on Windows
coverity: allow running on macOS
coverity: detect and report when the token or project is incorrect
John Cai (3):
merge-ort: initialize repo in index state
attr: read attributes from HEAD when bare repo
attr: add attr.tree for setting the treeish to read attributes from
Josh Soref (1):
Documentation/git-status: add missing line breaks
Josip Sokcevic (1):
diff-lib: fix check_removed when fsmonitor is on
Junio C Hamano (49):
update-index: do not read HEAD and MERGE_HEAD unconditionally
resolve-undo: allow resurrecting conflicted state that resolved to deletion
update-index: use unmerge_index_entry() to support removal
update-index: remove stale fallback code for "--unresolve"
checkout/restore: refuse unmerging paths unless checking out of the index
checkout/restore: add basic tests for --merge
checkout: allow "checkout -m path" to unmerge removed paths
mv: fix error for moving directory to another
diff: move the fallback "--exit-code" code down
diff: mode-only change should be noticed by "--patch -w --exit-code"
diff: teach "--stat -w --exit-code" to notice differences
t4040: remove test that succeeded for a wrong reason
pretty-formats: define "literal formatting code"
diff: spell DIFF_INDEX_CACHED out when calling run_diff_index()
diff: the -w option breaks --exit-code for --raw and other output modes
transfer.unpackLimit: fetch/receive.unpackLimit takes precedence
Start the 2.43 cycle
The second batch for 2.43
The extra batch to update credenthal helpers
The third batch
The fourth batch
The fifth batch
The sixth batch
The seventh batch
update-index doc: v4 is OK with JGit and libgit2
update-index: add --show-index-version
test-tool: retire "index-version"
The eighth batch
The ninth batch
The tenth batch
The eleventh batch
completion: loosen and document the requirement around completing alias
The twelfth batch
The thirteenth batch
The fourteenth batch
The fifteenth batch
doc: update list archive reference to use lore.kernel.org
The sixteenth batch
merge: introduce {copy|clear}_merge_options()
stash: be careful what we store
The seventeenth batch
The eighteenth batch
commit: do not use cryptic "new_index" in end-user facing messages
The nineteenth batch
am: align placeholder for --whitespace option with apply
The twentieth batch
The twenty-first batch
The twenty-second batch
Git 2.42.1
Kousik Sanagavarapu (4):
ref-filter: sort numerically when ":size" is used
t/t6300: cleanup test_atom
t/t6300: introduce test_bad_atom
ref-filter: add mailmap support
Kristoffer Haugsbakk (2):
range-diff: treat notes like `log`
grep: die gracefully when outside repository
Linus Arver (16):
trailer tests: make test cases self-contained
trailer test description: this tests --where=after, not --where=before
trailer: add tests to check defaulting behavior with --no-* flags
trailer doc: narrow down scope of --where and related flags
trailer: trailer location is a place, not an action
trailer --no-divider help: describe usual "---" meaning
trailer --parse help: expose aliased options
trailer --only-input: prefer "configuration variables" over "rules"
trailer --parse docs: add explanation for its usefulness
trailer --unfold help: prefer "reformat" over "join"
trailer doc: emphasize the effect of configuration variables
trailer doc: separator within key suppresses default separator
trailer doc: <token> is a <key> or <keyAlias>, not both
trailer: separate public from internal portion of trailer_iterator
trailer: split process_input_file into separate pieces
trailer: split process_command_line_args into separate functions
M Hickford (3):
credential/libsecret: store new attributes
credential/libsecret: erase matching creds only
credential/wincred: erase matching creds only
Mark Levedahl (6):
git gui Makefile - remove Cygwin modifications
git-gui - remove obsolete Cygwin specific code
git-gui - use cygstart to browse on Cygwin
git-gui - use mkshortcut on Cygwin
git-gui - re-enable use of hook scripts
git-gui - use git-hook, honor core.hooksPath
Mark Ruvald Pedersen (1):
sequencer: truncate labels to accommodate loose refs
Matthew McClain (1):
git-p4 shouldn't attempt to store symlinks in LFS
Michal Suchanek (1):
git-push doc: more visibility for -q option
Naomi Ibe (1):
builtin/add.c: clean up die() messages
Oswald Buddenhagen (16):
t/lib-rebase: set_fake_editor(): fix recognition of reset's short command
t/lib-rebase: set_fake_editor(): handle FAKE_LINES more consistently
sequencer: simplify allocation of result array in todo_list_rearrange_squash()
t/lib-rebase: improve documentation of set_fake_editor()
t9001: fix indentation in test_no_confirm()
format-patch: add --description-file option
sequencer: rectify empty hint in call of require_clean_work_tree()
sequencer: beautify subject of reverts of reverts
git-revert.txt: add discussion
sequencer: fix error message on failure to copy SQUASH_MSG
t3404-rebase-interactive.sh: fix typos in title of a rewording test
sequencer: remove unreachable exit condition in pick_commits()
am: fix error message in parse_opt_show_current_patch()
rebase: simplify code related to imply_merge()
rebase: handle --strategy via imply_merge() as well
rebase: move parse_opt_keep_empty() down
Patrick Steinhardt (5):
upload-pack: fix exit code when denying fetch of unreachable object ID
revision: make pseudo-opt flags read via stdin behave consistently
doc/git-worktree: mention "refs/rewritten" as per-worktree refs
doc/git-repack: fix syntax for `-g` shorthand option
doc/git-repack: don't mention nonexistent "--unpacked" option
Philippe Blain (3):
completion: commit: complete configured trailer tokens
completion: commit: complete trailers tokens more robustly
completion: improve doc for complex aliases
Phillip Wood (7):
rebase -i: move unlink() calls
rebase -i: remove patch file after conflict resolution
sequencer: use rebase_path_message()
sequencer: factor out part of pick_commits()
rebase: fix rewritten list for failed pick
rebase --continue: refuse to commit after failed command
rebase -i: fix adding failed command to the todo list
René Scharfe (14):
subtree: disallow --no-{help,quiet,debug,branch,message}
t1502, docs: disallow --no-help
t1502: move optionspec help output to a file
t1502: test option negation
parse-options: show negatability of options in short help
parse-options: factor out usage_indent() and usage_padding()
parse-options: no --[no-]no-...
parse-options: simplify usage_padding()
parse-options: allow omitting option help text
name-rev: use OPT_HIDDEN_BOOL for --peel-tag
grep: use OPT_INTEGER_F for --max-depth
grep: reject --no-or
diff --no-index: fix -R with stdin
parse-options: drop unused parse_opt_ctx_t member
Rubén Justo (2):
branch: error message deleting a branch in use
branch: error message checking out a branch in use
Sergey Organov (4):
doc/diff-options: fix link to generating patch section
diff-merges: improve --diff-merges documentation
diff-merges: introduce '--dd' option
completion: complete '--dd'
Shuqi Liang (3):
t1092: add tests for 'git check-attr'
attr.c: read attributes in a sparse directory
check-attr: integrate with sparse-index
Tang Yuyi (1):
merge-tree: add -X strategy option
Taylor Blau (24):
repack: move `pack_geometry` struct to the stack
commit-graph: introduce `commit_graph_generation_from_graph()`
t/t5318-commit-graph.sh: test generation zero transitions during fsck
commit-graph: avoid repeated mixed generation number warnings
leak tests: mark a handful of tests as leak-free
leak tests: mark t3321-notes-stripspace.sh as leak-free
leak tests: mark t5583-push-branches.sh as leak-free
builtin/pack-objects.c: remove unnecessary strbuf_reset()
builtin/pack-objects.c: support `--max-pack-size` with `--cruft`
Documentation/gitformat-pack.txt: remove multi-cruft packs alternative
Documentation/gitformat-pack.txt: drop mixed version section
builtin/repack.c: extract structure to store existing packs
builtin/repack.c: extract marking packs for deletion
builtin/repack.c: extract redundant pack cleanup for --geometric
builtin/repack.c: extract redundant pack cleanup for existing packs
builtin/repack.c: extract `has_existing_non_kept_packs()`
builtin/repack.c: store existing cruft packs separately
builtin/repack.c: avoid directly inspecting "util"
builtin/repack.c: extract common cruft pack loop
git-send-email.perl: avoid printing undef when validating addresses
t7700: split cruft-related tests to t7704
builtin/repack.c: parse `--max-pack-size` with OPT_MAGNITUDE
builtin/repack.c: implement support for `--max-cruft-size`
builtin/repack.c: avoid making cruft packs preferred
Victoria Dye (4):
ref-cache.c: fix prefix matching in ref iteration
dir.[ch]: expose 'get_dtype'
dir.[ch]: add 'follow_symlink' arg to 'get_dtype'
files-backend.c: avoid stat in 'loose_fill_ref_dir'
Vipul Kumar (1):
git-gui: Fix a typo in README
Wesley Schwengle (2):
git-push.txt: fix grammar
git-svn: drop FakeTerm hack
brian m. carlson (1):
t: add a test helper to truncate files
Ævar Arnfjörð Bjarmason (1):
Makefiles: change search through $(MAKEFLAGS) for GNU make 4.4
Štěpán Němec (6):
doc: fix some typos, grammar and wording issues
doc/diff-options: improve wording of the log.diffMerges mention
git-jump: admit to passing merge mode args to ls-files
doc/gitk: s/sticked/stuck/
t/README: fix multi-prerequisite example
doc/cat-file: make synopsis and description less confusing
王常新 (1):
merge-ort.c: fix typo 'neeed' to 'needed'
谢致邦 (XIE Zhibang) (2):
doc: correct the 50 characters soft limit
doc: correct the 50 characters soft limit (+)
^ permalink raw reply
* [ANNOUNCE] Git v2.42.1
From: Junio C Hamano @ 2023-11-02 17:36 UTC (permalink / raw)
To: git; +Cc: Linux Kernel, git-packagers
The latest maintenance release Git v2.42.1 is now available at
the usual places.
There is nothing exciting to see here. Relative to Git 2.42, this
release contains the fixes that have already been merged to the
'master' branch of the development towards Git 2.43 that has been
tagged as Git 2.43.0-rc0.
The tarballs are found at:
https://www.kernel.org/pub/software/scm/git/
The following public repositories all have a copy of the 'v2.42.1'
tag and the 'maint' branch that the tag points at:
url = https://git.kernel.org/pub/scm/git/git
url = https://kernel.googlesource.com/pub/scm/git/git
url = git://repo.or.cz/alt-git.git
url = https://github.com/gitster/git
----------------------------------------------------------------
Git 2.42.1 Release Notes
========================
There is nothing exciting to see here. Relative to Git 2.42, this
release contains the fixes that have already been merged to the
'master' branch of the development towards Git 2.43 that has been
tagged as Git 2.43.0-rc0.
Fixes since Git 2.42.0
----------------------
* Tests that are known to pass with LSan are now marked as such.
* Flaky "git p4" tests, as well as "git svn" tests, are now skipped
in the (rather expensive) sanitizer CI job.
* Tests with LSan from time to time seem to emit harmless message
that makes our tests unnecessarily flaky; we work it around by
filtering the uninteresting output.
* GitHub CI workflow has learned to trigger Coverity check.
* Overly long label names used in the sequencer machinery are now
chopped to fit under filesystem limitation.
* Scalar updates.
* Tweak GitHub Actions CI so that pushing the same commit to multiple
branch tips at the same time will not waste building and testing
the same thing twice.
* The commit-graph verification code that detects mixture of zero and
non-zero generation numbers has been updated.
* "git diff -w --exit-code" with various options did not work
correctly, which is being addressed.
* transfer.unpackLimit ought to be used as a fallback, but overrode
fetch.unpackLimit and receive.unpackLimit instead.
* The use of API between two calls to require_clean_work_tree() from
the sequencer code has been cleaned up for consistency.
* "git diff --no-such-option" and other corner cases around the exit
status of the "diff" command has been corrected.
* "git for-each-ref --sort='contents:size'" sorts the refs according
to size numerically, giving a ref that points at a blob twelve-byte
(12) long before showing a blob hundred-byte (100) long.
* Various fixes to the behavior of "rebase -i" when the command got
interrupted by conflicting changes.
* References from description of the `--patch` option in various
manual pages have been simplified and improved.
* "git grep -e A --no-or -e B" is accepted, even though the negation
of "or" did not mean anything, which has been tightened.
* The completion script (in contrib/) has been taught to treat the
"-t" option to "git checkout" and "git switch" just like the
"--track" option, to complete remote-tracking branches.
* "git diff --no-index -R <(one) <(two)" did not work correctly,
which has been corrected.
* Update "git maintenance" timers' implementation based on systemd
timers to work with WSL.
* "git diff --cached" codepath did not fill the necessary stat
information for a file when fsmonitor knows it is clean and ended
up behaving as if it is not clean, which has been corrected.
* Clarify how "alias.foo = : git cmd ; aliased-command-string" should
be spelled with necessary whitespaces around punctuation marks to
work.
* HTTP Header redaction code has been adjusted for a newer version of
cURL library that shows its traces differently from earlier
versions.
* An error message given by "git send-email" when given a malformed
address did not give correct information, which has been corrected.
* UBSan options were not propagated through the test framework to git
run via the httpd, unlike ASan options, which has been corrected.
Also contains various documentation updates, code clean-ups and minor fixups.
----------------------------------------------------------------
Changes since v2.42.0 are as follows:
Caleb Hill (1):
git-clean doc: fix "without do cleaning" typo
Christian Hesse (2):
t/lib-gpg: forcibly run a trustdb update
t/t6300: drop magic filtering
Derrick Stolee (4):
upload-pack: fix race condition in error messages
scalar: add --[no-]src option
setup: add discover_git_directory_reason()
scalar reconfigure: help users remove buggy repos
Evan Gates (1):
git-config: fix misworded --type=path explanation
Han Young (1):
show doc: redirect user to git log manual instead of git diff-tree
Jacob Abel (1):
builtin/worktree.c: fix typo in "forgot fetch" msg
Jeff King (17):
hashmap: use expected signatures for comparison functions
diff-files: avoid negative exit value
diff: show usage for unknown builtin_diff_files() options
diff: die when failing to read index in git-diff builtin
diff: drop useless return from run_diff_{files,index} functions
diff: drop useless return values in git-diff helpers
diff: drop useless "status" parameter from diff_result_code()
commit-graph: verify swapped zero/non-zero generation cases
test-lib: ignore uninteresting LSan output
ci: allow branch selection through "vars"
ci: deprecate ci/config/allow-ref script
http: factor out matching of curl http/2 trace lines
http: update curl http/2 info matching for curl 8.3.0
test-lib: set UBSAN_OPTIONS to match ASan
decorate: add clear_decoration() function
revision: clear decoration structs during release_revisions()
daemon: free listen_addr before returning
Johannes Schindelin (12):
rebase: allow overriding the maximal length of the generated labels
ci: avoid building from the same commit in parallel
ci(linux-asan-ubsan): let's save some time
var: avoid a segmentation fault when `HOME` is unset
completion(switch/checkout): treat --track and -t the same
maintenance(systemd): support the Windows Subsystem for Linux
ci: add a GitHub workflow to submit Coverity scans
coverity: cache the Coverity Build Tool
coverity: allow overriding the Coverity project
coverity: support building on Windows
coverity: allow running on macOS
coverity: detect and report when the token or project is incorrect
Josip Sokcevic (1):
diff-lib: fix check_removed when fsmonitor is on
Junio C Hamano (12):
mv: fix error for moving directory to another
diff: move the fallback "--exit-code" code down
diff: mode-only change should be noticed by "--patch -w --exit-code"
diff: teach "--stat -w --exit-code" to notice differences
t4040: remove test that succeeded for a wrong reason
diff: spell DIFF_INDEX_CACHED out when calling run_diff_index()
diff: the -w option breaks --exit-code for --raw and other output modes
transfer.unpackLimit: fetch/receive.unpackLimit takes precedence
doc: update list archive reference to use lore.kernel.org
commit: do not use cryptic "new_index" in end-user facing messages
am: align placeholder for --whitespace option with apply
Git 2.42.1
Kousik Sanagavarapu (1):
ref-filter: sort numerically when ":size" is used
Mark Ruvald Pedersen (1):
sequencer: truncate labels to accommodate loose refs
Michal Suchanek (1):
git-push doc: more visibility for -q option
Naomi Ibe (1):
builtin/add.c: clean up die() messages
Oswald Buddenhagen (6):
t9001: fix indentation in test_no_confirm()
sequencer: rectify empty hint in call of require_clean_work_tree()
sequencer: fix error message on failure to copy SQUASH_MSG
t3404-rebase-interactive.sh: fix typos in title of a rewording test
sequencer: remove unreachable exit condition in pick_commits()
am: fix error message in parse_opt_show_current_patch()
Patrick Steinhardt (4):
upload-pack: fix exit code when denying fetch of unreachable object ID
doc/git-worktree: mention "refs/rewritten" as per-worktree refs
doc/git-repack: fix syntax for `-g` shorthand option
doc/git-repack: don't mention nonexistent "--unpacked" option
Philippe Blain (1):
completion: improve doc for complex aliases
Phillip Wood (7):
rebase -i: move unlink() calls
rebase -i: remove patch file after conflict resolution
sequencer: use rebase_path_message()
sequencer: factor out part of pick_commits()
rebase: fix rewritten list for failed pick
rebase --continue: refuse to commit after failed command
rebase -i: fix adding failed command to the todo list
René Scharfe (5):
name-rev: use OPT_HIDDEN_BOOL for --peel-tag
grep: use OPT_INTEGER_F for --max-depth
grep: reject --no-or
diff --no-index: fix -R with stdin
parse-options: drop unused parse_opt_ctx_t member
Sergey Organov (1):
doc/diff-options: fix link to generating patch section
Taylor Blau (7):
commit-graph: introduce `commit_graph_generation_from_graph()`
t/t5318-commit-graph.sh: test generation zero transitions during fsck
commit-graph: avoid repeated mixed generation number warnings
leak tests: mark a handful of tests as leak-free
leak tests: mark t3321-notes-stripspace.sh as leak-free
leak tests: mark t5583-push-branches.sh as leak-free
git-send-email.perl: avoid printing undef when validating addresses
Wesley Schwengle (2):
git-push.txt: fix grammar
git-svn: drop FakeTerm hack
Štěpán Němec (1):
doc/cat-file: make synopsis and description less confusing
王常新 (1):
merge-ort.c: fix typo 'neeed' to 'needed'
^ permalink raw reply
* Re: [PATCH v3 1/2] git-merge-file doc: drop "-file" from argument placeholders
From: Junio C Hamano @ 2023-11-02 16:28 UTC (permalink / raw)
To: Martin Ågren
Cc: brian m. carlson, git, Elijah Newren, Phillip Wood, Eric Sunshine,
Taylor Blau
In-Reply-To: <CAN0heSrv7MPcEwkq4uEtv9uBbqm4FLKQLE3gdsEbqKkxPXOj5A@mail.gmail.com>
Martin Ågren <martin.agren@gmail.com> writes:
> Maybe you having a similar reaction a second time makes this smell a bit
> more?
Not at all. I am perfectly OK with --object-*, not --blob-*, as the
end-user facing option name. I however strongly prefer to see our
log messages record the thought behind the design accurately in
order to help future developers when they wonder what our intention
was back when the commit was created.
In this case, I want to see that we tell our future selves "even
though we named the option 'object', we plan to support blobs and
nothing else, at least for now".
Thanks.
^ permalink raw reply
* Re: [PATCH v5 00/14] Introduce new `git replay` command
From: Christian Couder @ 2023-11-02 15:06 UTC (permalink / raw)
To: Johannes Schindelin, Elijah Newren
Cc: git, Junio C Hamano, Patrick Steinhardt, John Cai, Derrick Stolee,
Phillip Wood, Calvin Wan, Toon Claes, Dragan Simic, Linus Arver
In-Reply-To: <bd872b81-80a9-5e4e-dcb6-faebc9671848@gmx.de>
Hi Dscho and Elijah,
On Thu, Oct 26, 2023 at 3:44 PM Johannes Schindelin
<Johannes.Schindelin@gmx.de> wrote:
> In addition, I am still a bit uneasy with introducing both the manual page
> and the test script in this commit (see my comments in
> https://lore.kernel.org/git/03460733-0219-c648-5757-db1958f8042e@gmx.de/).
> It would be better to uphold our high standard and introduce scaffolds for
> both files in the first commit, then populate the file contents
> incrementally in the same the patches that introduce the corresponding
> options/features/changes.
I have tried to improve on that in the v6 I just sent, but there are
many patches implementing changes in behavior that I think weren't
worth documenting and testing in `test-tool fast-rebase` (which had no
doc and no test) and that aren't worth documenting and testing
specifically in `git replay` either.
Thanks!
^ permalink raw reply
* Re: [PATCH v5 00/14] Introduce new `git replay` command
From: Christian Couder @ 2023-11-02 14:59 UTC (permalink / raw)
To: Elijah Newren
Cc: Johannes Schindelin, git, Junio C Hamano, Patrick Steinhardt,
John Cai, Derrick Stolee, Phillip Wood, Calvin Wan, Toon Claes,
Dragan Simic, Linus Arver
In-Reply-To: <CABPp-BFrVfGHOrBk7g=4TkGxDv=oSqF1FOkhp6WVbxUV-2yveQ@mail.gmail.com>
On Sun, Oct 29, 2023 at 7:02 AM Elijah Newren <newren@gmail.com> wrote:
> On Thu, Oct 26, 2023 at 6:44 AM Johannes Schindelin
> <Johannes.Schindelin@gmx.de> wrote:
> > On Tue, 10 Oct 2023, Christian Couder wrote:
> >
> [...]
> > > + /* requirements/overrides for revs */
> > > -+ revs.reverse = 1;
> > > ++ revs.reverse = !revs.reverse;
> > > + revs.sort_order = REV_SORT_IN_GRAPH_ORDER;
> > > + revs.topo_order = 1;
> > > + revs.simplify_history = 0;
> >
> > This still overrides a couple of command-line options, _silently_. I would
> > prefer those three assignments to be moved just before the
> > `setup_revisions()` call.
> >
> > Letting users override these settings may not make much sense, but it
> > makes even less sense to pretend to let them override the settings and
> > then just ignore them without warning. (See also
> > https://en.wikipedia.org/wiki/Principle_of_least_astonishment.)
> >
> > Moving these three assignments before the `setup_revisions()` call would
> > neatly remedy that.
>
> I agree that warnings or error messages would be better.
Ok, a warning() is emitted now in case an command-line option will be
overridden.
> But if we're talking about something short of that, I'd actually argue
> the opposite of what you do here. I intentionally moved these
> assignments after setup_revisions(), and in my mind, the purpose in
> doing so was to satisfy the Principle of Least Astonishment. My
> experience with git-fast-export, where some settings are made before
> calling setup_revisions() and then can be overridden, and then do
> completely hideous things, was much worse to me than just admitting
> the flags are bad given the various assumptions the tool makes. I
> have some patches sitting around to fix fast-export that I never got
> around to upstreaming, but when it came time to implement git-replay,
> I made sure to fix what I viewed as the bigger problem.
I hope you will be able to upstream such changes.
> [...]
> > > @@ Documentation/git-replay.txt (new)
> > > +
> > > +NAME
> > > +----
> > > -+git-replay - Replay commits on a different base, without touching working tree
> > > ++git-replay - Replay commits on a new base, works on bare repos too
> > > +
> > > +
> > > +SYNOPSIS
> >
> > As mentioned in
> > https://lore.kernel.org/git/03460733-0219-c648-5757-db1958f8042e@gmx.de/,
> > I would like the `EXPERIMENTAL` label to be shown prominently here.
> > Probably not only the `SYNOPSIS` as I had originally suggested but also in
> > the `NAME`.
Ok, I have made changes in the v6 I just sent, so that there is
EXPERIMENTAL both in the NAME and SYNOPSIS.
> > Otherwise we may end up with the same situation as with the (from my
> > perspective, failed) `git switch`/`git restore` experiment, where we
> > wanted to explore a better user experience than the overloaded `git
> > checkout` command, only to now be stuck with having to maintain
> > backward-compatibility for `git switch`/`git restore` command-line options
> > that were not meant to be set in stone but to be iterated on, instead. A
> > real-life demonstration of [Hyrum's Law](hyrumslaw.com/), if you like. Or,
> > from a different angle, we re-enacted https://xkcd.com/927/ in a way.
Nit: Hyrum's Law says:
"With a sufficient number of users of an API,
it does not matter what you promise in the contract:
all observable behaviors of your system
will be depended on by somebody."
The doc is part of the contract, which according to this law doesn't
matter. So I don't see why you use this law to suggest a doc change.
> > I'd like to suggest to learn from history and avoid this by tacking on a
> > warning label right at the top of the documentation. We may eventually
> > manage to iterate `git replay` to a point where it is totally capable to
> > supersede `git rebase`, by doing everything the latter does, except
> > better, who knows? But we _do_ need the liberty to make sweeping changes
> > to this new builtin if we want to have a prayer of doing that. And I fear
> > that not even mentioning the EXPERIMENTAL nature right at the top of the
> > manual page would just render us into that undesirable corner.
>
> I fully support this. Absolutely, 100%.
Ok. Note that as I changed the SYNOPSIS, I also had to change the
usage string, so that it matches the SYNOPSIS, otherwise a test would
fail. So there is "EXPERIMENTAL" in the usage string too.
^ permalink raw reply
* Re: [PATCH v5 00/14] Introduce new `git replay` command
From: Christian Couder @ 2023-11-02 14:48 UTC (permalink / raw)
To: Elijah Newren
Cc: git, Junio C Hamano, Patrick Steinhardt, Johannes Schindelin,
John Cai, Derrick Stolee, Phillip Wood, Calvin Wan, Toon Claes,
Dragan Simic, Linus Arver
In-Reply-To: <CABPp-BGCzxL-kpOvZzWRTJcx2v18QHm5ev8bFv7bm0dyNqhKug@mail.gmail.com>
On Sun, Oct 29, 2023 at 7:00 AM Elijah Newren <newren@gmail.com> wrote:
> On Tue, Oct 10, 2023 at 5:39 AM Christian Couder
> <christian.couder@gmail.com> wrote:
> > @@ Documentation/git-replay.txt (new)
> > +
> > +NAME
> > +----
> > -+git-replay - Replay commits on a different base, without touching working tree
> > ++git-replay - Replay commits on a new base, works on bare repos too
>
> really minor point: "works on" or "works in" or "works with" ?
I have changed it to "works with", I hope it sounds better. Also I
forgot to talk about this change in the cover letter, sorry about
that.
^ permalink raw reply
* Re: [PATCH v5 00/14] Introduce new `git replay` command
From: Christian Couder @ 2023-11-02 14:44 UTC (permalink / raw)
To: Elijah Newren, Johannes Schindelin
Cc: git, Junio C Hamano, Patrick Steinhardt, John Cai, Derrick Stolee,
Phillip Wood, Calvin Wan, Toon Claes, Dragan Simic, Linus Arver
In-Reply-To: <CABPp-BGfsda-8CK7_YPJfhGMfpLqdDeB8X6wnqPAGmhiY4KjDA@mail.gmail.com>
Hi Elijah and Dscho,
On Mon, Oct 30, 2023 at 6:18 PM Elijah Newren <newren@gmail.com> wrote:
> On Sun, Oct 29, 2023 at 7:14 AM Johannes Schindelin
> <Johannes.Schindelin@gmx.de> wrote:
> > On Sat, 28 Oct 2023, Elijah Newren wrote:
> > > I can see why this might sometimes be useful for exclusively linear
> > > history, but it seems to open a can of worms and possibly unfixable
> > > corner cases for non-linear history. I'd rather not do this, or at
> > > least pull it out of this series and let us discuss it in some follow
> > > up series. There are some other alternatives that might handle such
> > > usecases better.
> >
> > I find myself wishing for an easy way to reverse commits, if only to
> > switch around the latest two commits while stopped during a rebase.
> >
> > So it would have been nice for me if there had been an easy, worktree-less
> > way to make that happen.
>
> Seems reasonable; we'll definitely want to keep this in mind.
>
> > I guess this would be going in the direction of reordering commits,
> > though, something we deliberately left for later?
>
> Yes, I think that's a good framing for it.
Ok, in the v6 I just sent, a warning() is emitted when `--reverse` is
passed and the option has no effect.
I agree that handling such options in a better way should be left for
later patch series.
Thanks both!
^ permalink raw reply
* Re: why does git set X in LESS env var?
From: Dragan Simic @ 2023-11-02 14:19 UTC (permalink / raw)
To: Thomas Guyot; +Cc: Junio C Hamano, Jeff King, Christoph Anton Mitterer, git
In-Reply-To: <d54eedf0-7825-44f5-908c-a51541345872@gmail.com>
On 2023-11-02 14:19, Thomas Guyot wrote:
> On 2023-11-02 02:48, Dragan Simic wrote:
>> On 2023-11-02 06:48, Thomas Guyot wrote:
>>> -c or --clear-screen ( and backward compat. -C or
>>> --CLEAR-SCREEN )
>>> Causes full screen repaints to be painted from the top
>>> line down. By default, full screen repaints are done by scrolling
>>> from the bottom of the screen.
>>
>> AFAIK, the "-c" option is about the way screen contents is updated
>> when
>> scrolled, and it exists to aid in resolving possible issues with some
>> terminal emulators. To make sure, I just tested it, and "-c" doesn't
>> replace "-X".
>
> That's correct, you need both and also -y0
Hmm, I tried the following:
GIT_PAGER='less -R -F -X -c -y0'
In my environment (Xfce), the result after scrolling the output of "git
log -p" up and down a bit was about 20 copies of the same screen "page"
in the scrollback, plus a couple of blank "pages". Not good,
unfortunately, and actually much worse than having just "-R -F -X".
>> Huh, this confuses me a bit, quite frankly. Isn't the "-F" option
>> used
>> specifically to make pagination invisible in case fewer lines than one
>> full screen are displayed?
>
> Indeed, but when less update from the bottom, it can add new lines and
> let the overflow lines scroll up into the scrollback buffer.
>
> Then updating it from the top, it draws the whole page, top to bottom.
> That's fine for a full page but not desired for a partial one. Also
> note that on my terminal (rxvt-unicode) when less clears the screen to
> draw the first page the current screen is rolled up into scrollback -
> iirc that's a configurable option, it would be worth testing other
> terminal's behavior on that. IIRC it may also erase it when using the
> wrong termcap file.
>
> I haven't looked at the code, but I think it could be possibly to
> start the -c behavior only after a full page is drawn, after exiting
> on partial pages, which would give us the best of both worlds.
Does the GIT_PAGER setup, as I described it above, work for you without
the described artifacts, in any of the environments you have access to?
>>> OTOH by repainting from the top, the scrollback buffer is never
>>> affected. only the last displayed page remains on the terminal.
>>
>> Just to clarify, it's the "-X" option that creates all the issues, and
>> the "--redraw-on-quit" option is already there to replace it with no
>> associated issues, but the trouble is that only newer versions of
>> less(1) support the "--redraw-on-quit" option. IOW, it's all about
>> improving less(1) to avoid complex workarounds required to handle
>> different versions, such as the workarounds used in bat(1).
>
> TBH I haven't tested --redraw-on-quit, even on Debian Bookworm which
> was just released a couple months ago this option isn't available. I
> suspect that the issue isn't -X, but the scrolling behavior controlled
> by -y and the full redraw controlled by -c.
When you get into the terminfo entry definitions, the root cause is that
the terminal initialization sequences contain switching to alternate
screen, which causes screen contents to be lost when less(1) exits.
Thus, "-X" has been actually abused in the pager setups to skip the
terminal initialization sequences, which may also result in other
issues.
One of the solutions is to edit the terminfo entry manually and remove
the escape codes that cause the switching to and from alternate screen,
which I tested, but that also introduced another issue -- the screen
contents was always present after less(1) exited, which isn't always the
desired behavior.
> Actually I just tested my
> solution on xfce4-terminal and it doesn't work, the terminal still
> push up stuff above on redraw (noteworthy is with rxvt-unicode the
> first draw pushes the current screen contents up but no other redraw
> does, which is what makes it work so well - I haven't tried to find
> out what is being done exactly... OTOH the redraw on scroll down is
> slightly noticeable there, while impossible to see on xfce4-terminal.
> I'll install the latest less and see what happens with --redraw on
Please test the "--redraw-on-quit" option, so far it's the best
available solution, IMHO.
>>> If less could only enable this behavior after the first full page
>>> draw, that would be perfect!
>>
>> Could you, please, elaborate a bit on that?
>
> I mentioned it slightly above, to be clear it would mean that:
>
> 1. less starts by just writing lined down as usual, making any lines
> above scroll up and overflow into the scrollback buffer as usual
> 2. If less draws less than a page, exits as before - the effective
> result is as if pager was cat
> 3. If less reaches a full page and still has lines to write, it turns
> on -c's behavior and further updates happen from the top of the
> screen, preventing scroll up (at least on rxvt-unicode)
>
> Now, if all other terms misbehave here, that's an issue, making this
> suggestion mostly useless. And considering the number of Windows users
> we absolutely need to test Windows Terminal, and should probably test
> MacOS's term too (whatever that is).
Quite frankly, I think that such a solution would be like "fixing the
fix, which is actually an abuse", as I described it above, eventually
introducing even more issues, instead of solving the original issue.
>>> Dragan, that may be useful if you're discussing with less
>>> developers...
>>
>> We've basically reached some kind of an agreement about the need for a
>> good solution, which turned out to be rather complex as a result of
>> being quite universal and extensible, which was required for it to,
>> hopefully, be accepted into less(1). Also, the author of less(1)
>> seems
>> to be quite busy with some other things, and he prefers to implement
>> new
>> features himself.
>>
>> We've also agreed on another new feature for less(1), hopefully, which
>> isn't exactly related, but should be quite useful. It's about the
>> secure mode for less(1).
>
> Feel free to cc me on your next correspondence. If there are mailing
> lists archives for the thread I'll fetch them as needed. We have at
> least one working term/switch combination, which IMO is a better start
> than nothing :)
Please test the "--redraw-on-quit" option, AFAICT that's all we need
(plus the already mentioned other improvements to less(1), to avoid the
version-dependent workarounds), and the distributions will eventually
catch up with the newer versions of less(1). If the whole thing has
worked for decades as-is, it can continue working that way for a year or
two until the packages get updated.
There's actually no two-way mailing list for less(1), the entire project
is pretty much a one-man show, so to speak. There's a GitHub page that
allows issues to be submitted, but I didn't use that, so I exchanged a
few private email messages instead with the author. I've already summed
up the important parts of those messages.
^ permalink raw reply
* [PATCH v6 14/14] replay: stop assuming replayed branches do not diverge
From: Christian Couder @ 2023-11-02 13:51 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Patrick Steinhardt, Johannes Schindelin,
Elijah Newren, John Cai, Derrick Stolee, Phillip Wood, Calvin Wan,
Toon Claes, Dragan Simic, Linus Arver, Christian Couder
In-Reply-To: <20231102135151.843758-1-christian.couder@gmail.com>
From: Elijah Newren <newren@gmail.com>
The replay command is able to replay multiple branches but when some of
them are based on other replayed branches, their commit should be
replayed onto already replayed commits.
For this purpose, let's store the replayed commit and its original
commit in a key value store, so that we can easily find and reuse a
replayed commit instead of the original one.
Co-authored-by: Christian Couder <chriscool@tuxfamily.org>
Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
---
builtin/replay.c | 44 ++++++++++++++++++++++++++--------
t/t3650-replay-basics.sh | 52 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 86 insertions(+), 10 deletions(-)
diff --git a/builtin/replay.c b/builtin/replay.c
index 08ff9bab5e..c3d53ff0cd 100644
--- a/builtin/replay.c
+++ b/builtin/replay.c
@@ -223,20 +223,33 @@ static void determine_replay_mode(struct rev_cmdline_info *cmd_info,
strset_clear(&rinfo.positive_refs);
}
+static struct commit *mapped_commit(kh_oid_map_t *replayed_commits,
+ struct commit *commit,
+ struct commit *fallback)
+{
+ khint_t pos = kh_get_oid_map(replayed_commits, commit->object.oid);
+ if (pos == kh_end(replayed_commits))
+ return fallback;
+ return kh_value(replayed_commits, pos);
+}
+
static struct commit *pick_regular_commit(struct commit *pickme,
- struct commit *last_commit,
+ kh_oid_map_t *replayed_commits,
+ struct commit *onto,
struct merge_options *merge_opt,
struct merge_result *result)
{
- struct commit *base;
+ struct commit *base, *replayed_base;
struct tree *pickme_tree, *base_tree;
base = pickme->parents->item;
+ replayed_base = mapped_commit(replayed_commits, base, onto);
+ result->tree = repo_get_commit_tree(the_repository, replayed_base);
pickme_tree = repo_get_commit_tree(the_repository, pickme);
base_tree = repo_get_commit_tree(the_repository, base);
- merge_opt->branch1 = short_commit_name(last_commit);
+ merge_opt->branch1 = short_commit_name(replayed_base);
merge_opt->branch2 = short_commit_name(pickme);
merge_opt->ancestor = xstrfmt("parent of %s", merge_opt->branch2);
@@ -250,7 +263,7 @@ static struct commit *pick_regular_commit(struct commit *pickme,
merge_opt->ancestor = NULL;
if (!result->clean)
return NULL;
- return create_commit(result->tree, pickme, last_commit);
+ return create_commit(result->tree, pickme, replayed_base);
}
int cmd_replay(int argc, const char **argv, const char *prefix)
@@ -266,6 +279,7 @@ int cmd_replay(int argc, const char **argv, const char *prefix)
struct merge_options merge_opt;
struct merge_result result;
struct strset *update_refs = NULL;
+ kh_oid_map_t *replayed_commits;
int i, ret = 0;
const char * const replay_usage[] = {
@@ -338,21 +352,30 @@ int cmd_replay(int argc, const char **argv, const char *prefix)
init_merge_options(&merge_opt, the_repository);
memset(&result, 0, sizeof(result));
merge_opt.show_rename_progress = 0;
-
- result.tree = repo_get_commit_tree(the_repository, onto);
last_commit = onto;
+ replayed_commits = kh_init_oid_map();
while ((commit = get_revision(&revs))) {
const struct name_decoration *decoration;
+ khint_t pos;
+ int hr;
if (!commit->parents)
die(_("replaying down to root commit is not supported yet!"));
if (commit->parents->next)
die(_("replaying merge commits is not supported yet!"));
- last_commit = pick_regular_commit(commit, last_commit, &merge_opt, &result);
+ last_commit = pick_regular_commit(commit, replayed_commits, onto,
+ &merge_opt, &result);
if (!last_commit)
break;
+ /* Record commit -> last_commit mapping */
+ pos = kh_put_oid_map(replayed_commits, commit->object.oid, &hr);
+ if (hr == 0)
+ BUG("Duplicate rewritten commit: %s\n",
+ oid_to_hex(&commit->object.oid));
+ kh_value(replayed_commits, pos) = last_commit;
+
/* Update any necessary branches */
if (advance_name)
continue;
@@ -381,13 +404,14 @@ int cmd_replay(int argc, const char **argv, const char *prefix)
}
merge_finalize(&merge_opt, &result);
- ret = result.clean;
-
-cleanup:
+ kh_destroy_oid_map(replayed_commits);
if (update_refs) {
strset_clear(update_refs);
free(update_refs);
}
+ ret = result.clean;
+
+cleanup:
release_revisions(&revs);
/* Return */
diff --git a/t/t3650-replay-basics.sh b/t/t3650-replay-basics.sh
index d6286f9580..389670262e 100755
--- a/t/t3650-replay-basics.sh
+++ b/t/t3650-replay-basics.sh
@@ -143,4 +143,56 @@ test_expect_success 'using replay on bare repo to also rebase a contained branch
test_cmp expect result-bare
'
+test_expect_success 'using replay to rebase multiple divergent branches' '
+ git replay --onto main ^topic1 topic2 topic4 >result &&
+
+ test_line_count = 2 result &&
+ cut -f 3 -d " " result >new-branch-tips &&
+
+ git log --format=%s $(head -n 1 new-branch-tips) >actual &&
+ test_write_lines E D M L B A >expect &&
+ test_cmp expect actual &&
+
+ git log --format=%s $(tail -n 1 new-branch-tips) >actual &&
+ test_write_lines J I M L B A >expect &&
+ test_cmp expect actual &&
+
+ printf "update refs/heads/topic2 " >expect &&
+ printf "%s " $(head -n 1 new-branch-tips) >>expect &&
+ git rev-parse topic2 >>expect &&
+ printf "update refs/heads/topic4 " >>expect &&
+ printf "%s " $(tail -n 1 new-branch-tips) >>expect &&
+ git rev-parse topic4 >>expect &&
+
+ test_cmp expect result
+'
+
+test_expect_success 'using replay on bare repo to rebase multiple divergent branches, including contained ones' '
+ git -C bare replay --contained --onto main ^main topic2 topic3 topic4 >result &&
+
+ test_line_count = 4 result &&
+ cut -f 3 -d " " result >new-branch-tips &&
+
+ >expect &&
+ for i in 2 1 3 4
+ do
+ printf "update refs/heads/topic$i " >>expect &&
+ printf "%s " $(grep topic$i result | cut -f 3 -d " ") >>expect &&
+ git -C bare rev-parse topic$i >>expect || return 1
+ done &&
+
+ test_cmp expect result &&
+
+ test_write_lines F C M L B A >expect1 &&
+ test_write_lines E D C M L B A >expect2 &&
+ test_write_lines H G F C M L B A >expect3 &&
+ test_write_lines J I M L B A >expect4 &&
+
+ for i in 1 2 3 4
+ do
+ git -C bare log --format=%s $(grep topic$i result | cut -f 3 -d " ") >actual &&
+ test_cmp expect$i actual || return 1
+ done
+'
+
test_done
--
2.42.0.496.g529a7fda40
^ permalink raw reply related
* [PATCH v6 13/14] replay: add --contained to rebase contained branches
From: Christian Couder @ 2023-11-02 13:51 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Patrick Steinhardt, Johannes Schindelin,
Elijah Newren, John Cai, Derrick Stolee, Phillip Wood, Calvin Wan,
Toon Claes, Dragan Simic, Linus Arver, Christian Couder
In-Reply-To: <20231102135151.843758-1-christian.couder@gmail.com>
From: Elijah Newren <newren@gmail.com>
Let's add a `--contained` option that can be used along with
`--onto` to rebase all the branches contained in the <revision-range>
argument.
Co-authored-by: Christian Couder <chriscool@tuxfamily.org>
Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
---
Documentation/git-replay.txt | 12 +++++++++++-
builtin/replay.c | 13 +++++++++++--
t/t3650-replay-basics.sh | 29 +++++++++++++++++++++++++++++
3 files changed, 51 insertions(+), 3 deletions(-)
diff --git a/Documentation/git-replay.txt b/Documentation/git-replay.txt
index e0c85cebf1..e7551aec54 100644
--- a/Documentation/git-replay.txt
+++ b/Documentation/git-replay.txt
@@ -9,7 +9,7 @@ git-replay - EXPERIMENTAL: Replay commits on a new base, works with bare repos t
SYNOPSIS
--------
[verse]
-'git replay' (--onto <newbase> | --advance <branch>) <revision-range>... # EXPERIMENTAL
+'git replay' ([--contained] --onto <newbase> | --advance <branch>) <revision-range>... # EXPERIMENTAL
DESCRIPTION
-----------
@@ -96,6 +96,16 @@ top of the exact same new base, they only differ in that the first
provides instructions to make mybranch point at the new commits and
the second provides instructions to make target point at them.
+What if you have a stack of branches, one depending upon another, and
+you'd really like to rebase the whole set?
+
+------------
+$ git replay --contained --onto origin/main origin/main..tipbranch
+update refs/heads/branch1 ${NEW_branch1_HASH} ${OLD_branch1_HASH}
+update refs/heads/branch2 ${NEW_branch2_HASH} ${OLD_branch2_HASH}
+update refs/heads/tipbranch ${NEW_tipbranch_HASH} ${OLD_tipbranch_HASH}
+------------
+
When calling `git replay`, one does not need to specify a range of
commits to replay using the syntax `A..B`; any range expression will
do:
diff --git a/builtin/replay.c b/builtin/replay.c
index 145ce9d9a3..08ff9bab5e 100644
--- a/builtin/replay.c
+++ b/builtin/replay.c
@@ -258,6 +258,7 @@ int cmd_replay(int argc, const char **argv, const char *prefix)
const char *advance_name = NULL;
struct commit *onto = NULL;
const char *onto_name = NULL;
+ int contained = 0;
struct rev_info revs;
struct commit *last_commit = NULL;
@@ -268,7 +269,8 @@ int cmd_replay(int argc, const char **argv, const char *prefix)
int i, ret = 0;
const char * const replay_usage[] = {
- N_("git replay (--onto <newbase> | --advance <branch>) <revision-range>... # EXPERIMENTAL"),
+ N_("git replay ([--contained] --onto <newbase> | --advance <branch>) "
+ "<revision-range>... # EXPERIMENTAL"),
NULL
};
struct option replay_options[] = {
@@ -278,6 +280,8 @@ int cmd_replay(int argc, const char **argv, const char *prefix)
OPT_STRING(0, "onto", &onto_name,
N_("revision"),
N_("replay onto given commit")),
+ OPT_BOOL(0, "contained", &contained,
+ N_("advance all branches contained in revision-range")),
OPT_END()
};
@@ -289,6 +293,10 @@ int cmd_replay(int argc, const char **argv, const char *prefix)
usage_with_options(replay_usage, replay_options);
}
+ if (advance_name && contained)
+ die(_("options '%s' and '%s' cannot be used together"),
+ "--advance", "--contained");
+
repo_init_revisions(the_repository, &revs, prefix);
/*
@@ -353,7 +361,8 @@ int cmd_replay(int argc, const char **argv, const char *prefix)
continue;
while (decoration) {
if (decoration->type == DECORATION_REF_LOCAL &&
- strset_contains(update_refs, decoration->name)) {
+ (contained || strset_contains(update_refs,
+ decoration->name))) {
printf("update %s %s %s\n",
decoration->name,
oid_to_hex(&last_commit->object.oid),
diff --git a/t/t3650-replay-basics.sh b/t/t3650-replay-basics.sh
index 68a87e7803..d6286f9580 100755
--- a/t/t3650-replay-basics.sh
+++ b/t/t3650-replay-basics.sh
@@ -114,4 +114,33 @@ test_expect_success 'replay fails when both --advance and --onto are omitted' '
test_must_fail git replay topic1..topic2 >result
'
+test_expect_success 'using replay to also rebase a contained branch' '
+ git replay --contained --onto main main..topic3 >result &&
+
+ test_line_count = 2 result &&
+ cut -f 3 -d " " result >new-branch-tips &&
+
+ git log --format=%s $(head -n 1 new-branch-tips) >actual &&
+ test_write_lines F C M L B A >expect &&
+ test_cmp expect actual &&
+
+ git log --format=%s $(tail -n 1 new-branch-tips) >actual &&
+ test_write_lines H G F C M L B A >expect &&
+ test_cmp expect actual &&
+
+ printf "update refs/heads/topic1 " >expect &&
+ printf "%s " $(head -n 1 new-branch-tips) >>expect &&
+ git rev-parse topic1 >>expect &&
+ printf "update refs/heads/topic3 " >>expect &&
+ printf "%s " $(tail -n 1 new-branch-tips) >>expect &&
+ git rev-parse topic3 >>expect &&
+
+ test_cmp expect result
+'
+
+test_expect_success 'using replay on bare repo to also rebase a contained branch' '
+ git -C bare replay --contained --onto main main..topic3 >result-bare &&
+ test_cmp expect result-bare
+'
+
test_done
--
2.42.0.496.g529a7fda40
^ permalink raw reply related
* [PATCH v6 12/14] replay: add --advance or 'cherry-pick' mode
From: Christian Couder @ 2023-11-02 13:51 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Patrick Steinhardt, Johannes Schindelin,
Elijah Newren, John Cai, Derrick Stolee, Phillip Wood, Calvin Wan,
Toon Claes, Dragan Simic, Linus Arver, Christian Couder
In-Reply-To: <20231102135151.843758-1-christian.couder@gmail.com>
From: Elijah Newren <newren@gmail.com>
There is already a 'rebase' mode with `--onto`. Let's add an 'advance' or
'cherry-pick' mode with `--advance`. This new mode will make the target
branch advance as we replay commits onto it.
The replayed commits should have a single tip, so that it's clear where
the target branch should be advanced. If they have more than one tip,
this new mode will error out.
Co-authored-by: Christian Couder <chriscool@tuxfamily.org>
Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
---
Documentation/git-replay.txt | 41 ++++++--
builtin/replay.c | 185 +++++++++++++++++++++++++++++++++--
t/t3650-replay-basics.sh | 34 +++++++
3 files changed, 243 insertions(+), 17 deletions(-)
diff --git a/Documentation/git-replay.txt b/Documentation/git-replay.txt
index 36ddd7daed..e0c85cebf1 100644
--- a/Documentation/git-replay.txt
+++ b/Documentation/git-replay.txt
@@ -9,7 +9,7 @@ git-replay - EXPERIMENTAL: Replay commits on a new base, works with bare repos t
SYNOPSIS
--------
[verse]
-'git replay' --onto <newbase> <revision-range>... # EXPERIMENTAL
+'git replay' (--onto <newbase> | --advance <branch>) <revision-range>... # EXPERIMENTAL
DESCRIPTION
-----------
@@ -29,14 +29,25 @@ OPTIONS
Starting point at which to create the new commits. May be any
valid commit, and not just an existing branch name.
+
-The update-ref command(s) in the output will update the branch(es) in
-the revision range to point at the new commits, similar to the way how
-`git rebase --update-refs` updates multiple branches in the affected
-range.
+When `--onto` is specified, the update-ref command(s) in the output will
+update the branch(es) in the revision range to point at the new
+commits, similar to the way how `git rebase --update-refs` updates
+multiple branches in the affected range.
+
+--advance <branch>::
+ Starting point at which to create the new commits; must be a
+ branch name.
++
+When `--advance` is specified, the update-ref command(s) in the output
+will update the branch passed as an argument to `--advance` to point at
+the new commits (in other words, this mimics a cherry-pick operation).
<revision-range>::
- Range of commits to replay; see "Specifying Ranges" in
- linkgit:git-rev-parse and the "Commit Limiting" options below.
+ Range of commits to replay. More than one <revision-range> can
+ be passed, but in `--advance <branch>` mode, they should have
+ a single tip, so that it's clear where <branch> should point
+ to. See "Specifying Ranges" in linkgit:git-rev-parse and the
+ "Commit Limiting" options below.
include::rev-list-options.txt[]
@@ -51,7 +62,9 @@ input to `git update-ref --stdin`. It is of the form:
update refs/heads/branch3 ${NEW_branch3_HASH} ${OLD_branch3_HASH}
where the number of refs updated depends on the arguments passed and
-the shape of the history being replayed.
+the shape of the history being replayed. When using `--advance`, the
+number of refs updated is always one, but for `--onto`, it can be one
+or more (rebasing multiple branches simultaneously is supported).
EXIT STATUS
-----------
@@ -71,6 +84,18 @@ $ git replay --onto target origin/main..mybranch
update refs/heads/mybranch ${NEW_mybranch_HASH} ${OLD_mybranch_HASH}
------------
+To cherry-pick the commits from mybranch onto target:
+
+------------
+$ git replay --advance target origin/main..mybranch
+update refs/heads/target ${NEW_target_HASH} ${OLD_target_HASH}
+------------
+
+Note that the first two examples replay the exact same commits and on
+top of the exact same new base, they only differ in that the first
+provides instructions to make mybranch point at the new commits and
+the second provides instructions to make target point at them.
+
When calling `git replay`, one does not need to specify a range of
commits to replay using the syntax `A..B`; any range expression will
do:
diff --git a/builtin/replay.c b/builtin/replay.c
index 8fe4391976..145ce9d9a3 100644
--- a/builtin/replay.c
+++ b/builtin/replay.c
@@ -14,6 +14,7 @@
#include "parse-options.h"
#include "refs.h"
#include "revision.h"
+#include "strmap.h"
#include <oidset.h>
#include <tree.h>
@@ -82,6 +83,146 @@ static struct commit *create_commit(struct tree *tree,
return (struct commit *)obj;
}
+struct ref_info {
+ struct commit *onto;
+ struct strset positive_refs;
+ struct strset negative_refs;
+ int positive_refexprs;
+ int negative_refexprs;
+};
+
+static void get_ref_information(struct rev_cmdline_info *cmd_info,
+ struct ref_info *ref_info)
+{
+ int i;
+
+ ref_info->onto = NULL;
+ strset_init(&ref_info->positive_refs);
+ strset_init(&ref_info->negative_refs);
+ ref_info->positive_refexprs = 0;
+ ref_info->negative_refexprs = 0;
+
+ /*
+ * When the user specifies e.g.
+ * git replay origin/main..mybranch
+ * git replay ^origin/next mybranch1 mybranch2
+ * we want to be able to determine where to replay the commits. In
+ * these examples, the branches are probably based on an old version
+ * of either origin/main or origin/next, so we want to replay on the
+ * newest version of that branch. In contrast we would want to error
+ * out if they ran
+ * git replay ^origin/master ^origin/next mybranch
+ * git replay mybranch~2..mybranch
+ * the first of those because there's no unique base to choose, and
+ * the second because they'd likely just be replaying commits on top
+ * of the same commit and not making any difference.
+ */
+ for (i = 0; i < cmd_info->nr; i++) {
+ struct rev_cmdline_entry *e = cmd_info->rev + i;
+ struct object_id oid;
+ const char *refexpr = e->name;
+ char *fullname = NULL;
+ int can_uniquely_dwim = 1;
+
+ if (*refexpr == '^')
+ refexpr++;
+ if (repo_dwim_ref(the_repository, refexpr, strlen(refexpr), &oid, &fullname, 0) != 1)
+ can_uniquely_dwim = 0;
+
+ if (e->flags & BOTTOM) {
+ if (can_uniquely_dwim)
+ strset_add(&ref_info->negative_refs, fullname);
+ if (!ref_info->negative_refexprs)
+ ref_info->onto = lookup_commit_reference_gently(the_repository,
+ &e->item->oid, 1);
+ ref_info->negative_refexprs++;
+ } else {
+ if (can_uniquely_dwim)
+ strset_add(&ref_info->positive_refs, fullname);
+ ref_info->positive_refexprs++;
+ }
+
+ free(fullname);
+ }
+}
+
+static void determine_replay_mode(struct rev_cmdline_info *cmd_info,
+ const char *onto_name,
+ const char **advance_name,
+ struct commit **onto,
+ struct strset **update_refs)
+{
+ struct ref_info rinfo;
+
+ get_ref_information(cmd_info, &rinfo);
+ if (!rinfo.positive_refexprs)
+ die(_("need some commits to replay"));
+ if (onto_name && *advance_name)
+ die(_("--onto and --advance are incompatible"));
+ else if (onto_name) {
+ *onto = peel_committish(onto_name);
+ if (rinfo.positive_refexprs <
+ strset_get_size(&rinfo.positive_refs))
+ die(_("all positive revisions given must be references"));
+ } else if (*advance_name) {
+ struct object_id oid;
+ char *fullname = NULL;
+
+ *onto = peel_committish(*advance_name);
+ if (repo_dwim_ref(the_repository, *advance_name, strlen(*advance_name),
+ &oid, &fullname, 0) == 1) {
+ *advance_name = fullname;
+ } else {
+ die(_("argument to --advance must be a reference"));
+ }
+ if (rinfo.positive_refexprs > 1)
+ die(_("cannot advance target with multiple sources because ordering would be ill-defined"));
+ } else {
+ int positive_refs_complete = (
+ rinfo.positive_refexprs ==
+ strset_get_size(&rinfo.positive_refs));
+ int negative_refs_complete = (
+ rinfo.negative_refexprs ==
+ strset_get_size(&rinfo.negative_refs));
+ /*
+ * We need either positive_refs_complete or
+ * negative_refs_complete, but not both.
+ */
+ if (rinfo.negative_refexprs > 0 &&
+ positive_refs_complete == negative_refs_complete)
+ die(_("cannot implicitly determine whether this is an --advance or --onto operation"));
+ if (negative_refs_complete) {
+ struct hashmap_iter iter;
+ struct strmap_entry *entry;
+
+ if (rinfo.negative_refexprs == 0)
+ die(_("all positive revisions given must be references"));
+ else if (rinfo.negative_refexprs > 1)
+ die(_("cannot implicitly determine whether this is an --advance or --onto operation"));
+ else if (rinfo.positive_refexprs > 1)
+ die(_("cannot advance target with multiple source branches because ordering would be ill-defined"));
+
+ /* Only one entry, but we have to loop to get it */
+ strset_for_each_entry(&rinfo.negative_refs,
+ &iter, entry) {
+ *advance_name = entry->key;
+ }
+ } else { /* positive_refs_complete */
+ if (rinfo.negative_refexprs > 1)
+ die(_("cannot implicitly determine correct base for --onto"));
+ if (rinfo.negative_refexprs == 1)
+ *onto = rinfo.onto;
+ }
+ }
+ if (!*advance_name) {
+ *update_refs = xcalloc(1, sizeof(**update_refs));
+ **update_refs = rinfo.positive_refs;
+ memset(&rinfo.positive_refs, 0, sizeof(**update_refs));
+ }
+ strset_clear(&rinfo.negative_refs);
+ strset_clear(&rinfo.positive_refs);
+}
+
static struct commit *pick_regular_commit(struct commit *pickme,
struct commit *last_commit,
struct merge_options *merge_opt,
@@ -114,20 +255,26 @@ static struct commit *pick_regular_commit(struct commit *pickme,
int cmd_replay(int argc, const char **argv, const char *prefix)
{
- struct commit *onto;
+ const char *advance_name = NULL;
+ struct commit *onto = NULL;
const char *onto_name = NULL;
- struct commit *last_commit = NULL;
+
struct rev_info revs;
+ struct commit *last_commit = NULL;
struct commit *commit;
struct merge_options merge_opt;
struct merge_result result;
+ struct strset *update_refs = NULL;
int i, ret = 0;
const char * const replay_usage[] = {
- N_("git replay --onto <newbase> <revision-range>... # EXPERIMENTAL"),
+ N_("git replay (--onto <newbase> | --advance <branch>) <revision-range>... # EXPERIMENTAL"),
NULL
};
struct option replay_options[] = {
+ OPT_STRING(0, "advance", &advance_name,
+ N_("branch"),
+ N_("make replay advance given branch")),
OPT_STRING(0, "onto", &onto_name,
N_("revision"),
N_("replay onto given commit")),
@@ -137,13 +284,11 @@ int cmd_replay(int argc, const char **argv, const char *prefix)
argc = parse_options(argc, argv, prefix, replay_options, replay_usage,
PARSE_OPT_KEEP_ARGV0 | PARSE_OPT_KEEP_UNKNOWN_OPT);
- if (!onto_name) {
- error(_("option --onto is mandatory"));
+ if (!onto_name && !advance_name) {
+ error(_("option --onto or --advance is mandatory"));
usage_with_options(replay_usage, replay_options);
}
- onto = peel_committish(onto_name);
-
repo_init_revisions(the_repository, &revs, prefix);
/*
@@ -171,6 +316,12 @@ int cmd_replay(int argc, const char **argv, const char *prefix)
revs.topo_order = 1;
revs.simplify_history = 0;
+ determine_replay_mode(&revs.cmdline, onto_name, &advance_name,
+ &onto, &update_refs);
+
+ if (!onto) /* FIXME: Should handle replaying down to root commit */
+ die("Replaying down to root commit is not supported yet!");
+
if (prepare_revision_walk(&revs) < 0) {
ret = error(_("error preparing revisions"));
goto cleanup;
@@ -179,6 +330,7 @@ int cmd_replay(int argc, const char **argv, const char *prefix)
init_merge_options(&merge_opt, the_repository);
memset(&result, 0, sizeof(result));
merge_opt.show_rename_progress = 0;
+
result.tree = repo_get_commit_tree(the_repository, onto);
last_commit = onto;
while ((commit = get_revision(&revs))) {
@@ -193,12 +345,15 @@ int cmd_replay(int argc, const char **argv, const char *prefix)
if (!last_commit)
break;
+ /* Update any necessary branches */
+ if (advance_name)
+ continue;
decoration = get_name_decoration(&commit->object);
if (!decoration)
continue;
-
while (decoration) {
- if (decoration->type == DECORATION_REF_LOCAL) {
+ if (decoration->type == DECORATION_REF_LOCAL &&
+ strset_contains(update_refs, decoration->name)) {
printf("update %s %s %s\n",
decoration->name,
oid_to_hex(&last_commit->object.oid),
@@ -208,10 +363,22 @@ int cmd_replay(int argc, const char **argv, const char *prefix)
}
}
+ /* In --advance mode, advance the target ref */
+ if (result.clean == 1 && advance_name) {
+ printf("update %s %s %s\n",
+ advance_name,
+ oid_to_hex(&last_commit->object.oid),
+ oid_to_hex(&onto->object.oid));
+ }
+
merge_finalize(&merge_opt, &result);
ret = result.clean;
cleanup:
+ if (update_refs) {
+ strset_clear(update_refs);
+ free(update_refs);
+ }
release_revisions(&revs);
/* Return */
diff --git a/t/t3650-replay-basics.sh b/t/t3650-replay-basics.sh
index a1da4f9ef9..68a87e7803 100755
--- a/t/t3650-replay-basics.sh
+++ b/t/t3650-replay-basics.sh
@@ -80,4 +80,38 @@ test_expect_success 'using replay on bare repo to rebase with a conflict' '
test_expect_code 1 git -C bare replay --onto topic1 B..conflict
'
+test_expect_success 'using replay to perform basic cherry-pick' '
+ # The differences between this test and previous ones are:
+ # --advance vs --onto
+ # 2nd field of result is refs/heads/main vs. refs/heads/topic2
+ # 4th field of result is hash for main instead of hash for topic2
+
+ git replay --advance main topic1..topic2 >result &&
+
+ test_line_count = 1 result &&
+
+ git log --format=%s $(cut -f 3 -d " " result) >actual &&
+ test_write_lines E D M L B A >expect &&
+ test_cmp expect actual &&
+
+ printf "update refs/heads/main " >expect &&
+ printf "%s " $(cut -f 3 -d " " result) >>expect &&
+ git rev-parse main >>expect &&
+
+ test_cmp expect result
+'
+
+test_expect_success 'using replay on bare repo to perform basic cherry-pick' '
+ git -C bare replay --advance main topic1..topic2 >result-bare &&
+ test_cmp expect result-bare
+'
+
+test_expect_success 'replay on bare repo fails with both --advance and --onto' '
+ test_must_fail git -C bare replay --advance main --onto main topic1..topic2 >result-bare
+'
+
+test_expect_success 'replay fails when both --advance and --onto are omitted' '
+ test_must_fail git replay topic1..topic2 >result
+'
+
test_done
--
2.42.0.496.g529a7fda40
^ permalink raw reply related
* [PATCH v6 11/14] replay: use standard revision ranges
From: Christian Couder @ 2023-11-02 13:51 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Patrick Steinhardt, Johannes Schindelin,
Elijah Newren, John Cai, Derrick Stolee, Phillip Wood, Calvin Wan,
Toon Claes, Dragan Simic, Linus Arver, Christian Couder
In-Reply-To: <20231102135151.843758-1-christian.couder@gmail.com>
From: Elijah Newren <newren@gmail.com>
Instead of the fixed "<oldbase> <branch>" arguments, the replay
command now accepts "<revision-range>..." arguments in a similar
way as many other Git commands. This makes its interface more
standard and more flexible.
This also enables many revision related options accepted and
eaten by setup_revisions(). If the replay command was a high level
one or had a high level mode, it would make sense to restrict some
of the possible options, like those generating non-contiguous
history, as they could be confusing for most users.
Also as the interface of the command is now mostly finalized,
we can add more documentation and more testcases to make sure
the command will continue to work as designed in the future.
We only document the rev-list related options among all the
revision related options that are now accepted, as the rev-list
related ones are probably the most useful for now.
Helped-by: Dragan Simic <dsimic@manjaro.org>
Helped-by: Linus Arver <linusa@google.com>
Co-authored-by: Christian Couder <chriscool@tuxfamily.org>
Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
---
Documentation/git-replay.txt | 55 +++++++++++++++++++++++-
builtin/replay.c | 21 ++-------
t/t3650-replay-basics.sh | 12 +++++-
t/t6429-merge-sequence-rename-caching.sh | 18 ++++----
4 files changed, 76 insertions(+), 30 deletions(-)
diff --git a/Documentation/git-replay.txt b/Documentation/git-replay.txt
index 4c852ff3bd..36ddd7daed 100644
--- a/Documentation/git-replay.txt
+++ b/Documentation/git-replay.txt
@@ -9,7 +9,7 @@ git-replay - EXPERIMENTAL: Replay commits on a new base, works with bare repos t
SYNOPSIS
--------
[verse]
-'git replay' --onto <newbase> <oldbase> <branch> # EXPERIMENTAL
+'git replay' --onto <newbase> <revision-range>... # EXPERIMENTAL
DESCRIPTION
-----------
@@ -17,7 +17,8 @@ DESCRIPTION
Takes a range of commits and replays them onto a new location. Leaves
the working tree and the index untouched, and updates no
references. The output of this command is meant to be used as input to
-`git update-ref --stdin`, which would update the relevant branches.
+`git update-ref --stdin`, which would update the relevant branches
+(see the OUTPUT section below).
THIS COMMAND IS EXPERIMENTAL. THE BEHAVIOR MAY CHANGE.
@@ -27,6 +28,30 @@ OPTIONS
--onto <newbase>::
Starting point at which to create the new commits. May be any
valid commit, and not just an existing branch name.
++
+The update-ref command(s) in the output will update the branch(es) in
+the revision range to point at the new commits, similar to the way how
+`git rebase --update-refs` updates multiple branches in the affected
+range.
+
+<revision-range>::
+ Range of commits to replay; see "Specifying Ranges" in
+ linkgit:git-rev-parse and the "Commit Limiting" options below.
+
+include::rev-list-options.txt[]
+
+OUTPUT
+------
+
+When there are no conflicts, the output of this command is usable as
+input to `git update-ref --stdin`. It is of the form:
+
+ update refs/heads/branch1 ${NEW_branch1_HASH} ${OLD_branch1_HASH}
+ update refs/heads/branch2 ${NEW_branch2_HASH} ${OLD_branch2_HASH}
+ update refs/heads/branch3 ${NEW_branch3_HASH} ${OLD_branch3_HASH}
+
+where the number of refs updated depends on the arguments passed and
+the shape of the history being replayed.
EXIT STATUS
-----------
@@ -36,6 +61,32 @@ the replay has conflicts, the exit status is 1. If the replay is not
able to complete (or start) due to some kind of error, the exit status
is something other than 0 or 1.
+EXAMPLES
+--------
+
+To simply rebase `mybranch` onto `target`:
+
+------------
+$ git replay --onto target origin/main..mybranch
+update refs/heads/mybranch ${NEW_mybranch_HASH} ${OLD_mybranch_HASH}
+------------
+
+When calling `git replay`, one does not need to specify a range of
+commits to replay using the syntax `A..B`; any range expression will
+do:
+
+------------
+$ git replay --onto origin/main ^base branch1 branch2 branch3
+update refs/heads/branch1 ${NEW_branch1_HASH} ${OLD_branch1_HASH}
+update refs/heads/branch2 ${NEW_branch2_HASH} ${OLD_branch2_HASH}
+update refs/heads/branch3 ${NEW_branch3_HASH} ${OLD_branch3_HASH}
+------------
+
+This will simultaneously rebase `branch1`, `branch2`, and `branch3`,
+all commits they have since `base`, playing them on top of
+`origin/main`. These three branches may have commits on top of `base`
+that they have in common, but that does not need to be the case.
+
GIT
---
Part of the linkgit:git[1] suite
diff --git a/builtin/replay.c b/builtin/replay.c
index 7e3ebac3db..8fe4391976 100644
--- a/builtin/replay.c
+++ b/builtin/replay.c
@@ -14,7 +14,6 @@
#include "parse-options.h"
#include "refs.h"
#include "revision.h"
-#include "strvec.h"
#include <oidset.h>
#include <tree.h>
@@ -118,16 +117,14 @@ int cmd_replay(int argc, const char **argv, const char *prefix)
struct commit *onto;
const char *onto_name = NULL;
struct commit *last_commit = NULL;
- struct strvec rev_walk_args = STRVEC_INIT;
struct rev_info revs;
struct commit *commit;
struct merge_options merge_opt;
struct merge_result result;
- struct strbuf branch_name = STRBUF_INIT;
int i, ret = 0;
const char * const replay_usage[] = {
- N_("git replay --onto <newbase> <oldbase> <branch> # EXPERIMENTAL"),
+ N_("git replay --onto <newbase> <revision-range>... # EXPERIMENTAL"),
NULL
};
struct option replay_options[] = {
@@ -145,18 +142,10 @@ int cmd_replay(int argc, const char **argv, const char *prefix)
usage_with_options(replay_usage, replay_options);
}
- if (argc != 3) {
- error(_("bad number of arguments"));
- usage_with_options(replay_usage, replay_options);
- }
-
onto = peel_committish(onto_name);
- strbuf_addf(&branch_name, "refs/heads/%s", argv[2]);
repo_init_revisions(the_repository, &revs, prefix);
- strvec_pushl(&rev_walk_args, "", argv[2], "--not", argv[1], NULL);
-
/*
* TODO: For now, let's warn when we see an option that we are
* going to override after setup_revisions() below. In the
@@ -170,8 +159,9 @@ int cmd_replay(int argc, const char **argv, const char *prefix)
warning(_("option '%s' will be overridden"), argv[i]);
}
- if (setup_revisions(rev_walk_args.nr, rev_walk_args.v, &revs, NULL) > 1) {
- ret = error(_("unhandled options"));
+ argc = setup_revisions(argc, argv, &revs, NULL);
+ if (argc > 1) {
+ ret = error(_("unrecognized argument: %s"), argv[1]);
goto cleanup;
}
@@ -181,8 +171,6 @@ int cmd_replay(int argc, const char **argv, const char *prefix)
revs.topo_order = 1;
revs.simplify_history = 0;
- strvec_clear(&rev_walk_args);
-
if (prepare_revision_walk(&revs) < 0) {
ret = error(_("error preparing revisions"));
goto cleanup;
@@ -224,7 +212,6 @@ int cmd_replay(int argc, const char **argv, const char *prefix)
ret = result.clean;
cleanup:
- strbuf_release(&branch_name);
release_revisions(&revs);
/* Return */
diff --git a/t/t3650-replay-basics.sh b/t/t3650-replay-basics.sh
index 3567c98362..a1da4f9ef9 100755
--- a/t/t3650-replay-basics.sh
+++ b/t/t3650-replay-basics.sh
@@ -52,7 +52,7 @@ test_expect_success 'setup bare' '
'
test_expect_success 'using replay to rebase two branches, one on top of other' '
- git replay --onto main topic1 topic2 >result &&
+ git replay --onto main topic1..topic2 >result &&
test_line_count = 1 result &&
@@ -68,8 +68,16 @@ test_expect_success 'using replay to rebase two branches, one on top of other' '
'
test_expect_success 'using replay on bare repo to rebase two branches, one on top of other' '
- git -C bare replay --onto main topic1 topic2 >result-bare &&
+ git -C bare replay --onto main topic1..topic2 >result-bare &&
test_cmp expect result-bare
'
+test_expect_success 'using replay to rebase with a conflict' '
+ test_expect_code 1 git replay --onto topic1 B..conflict
+'
+
+test_expect_success 'using replay on bare repo to rebase with a conflict' '
+ test_expect_code 1 git -C bare replay --onto topic1 B..conflict
+'
+
test_done
diff --git a/t/t6429-merge-sequence-rename-caching.sh b/t/t6429-merge-sequence-rename-caching.sh
index 099aefeffc..0f39ed0d08 100755
--- a/t/t6429-merge-sequence-rename-caching.sh
+++ b/t/t6429-merge-sequence-rename-caching.sh
@@ -71,7 +71,7 @@ test_expect_success 'caching renames does not preclude finding new ones' '
git switch upstream &&
- git replay --onto HEAD upstream~1 topic >out &&
+ git replay --onto HEAD upstream~1..topic >out &&
git update-ref --stdin <out &&
git checkout topic &&
@@ -141,7 +141,7 @@ test_expect_success 'cherry-pick both a commit and its immediate revert' '
GIT_TRACE2_PERF="$(pwd)/trace.output" &&
export GIT_TRACE2_PERF &&
- git replay --onto HEAD upstream~1 topic >out &&
+ git replay --onto HEAD upstream~1..topic >out &&
git update-ref --stdin <out &&
git checkout topic &&
@@ -201,7 +201,7 @@ test_expect_success 'rename same file identically, then reintroduce it' '
GIT_TRACE2_PERF="$(pwd)/trace.output" &&
export GIT_TRACE2_PERF &&
- git replay --onto HEAD upstream~1 topic >out &&
+ git replay --onto HEAD upstream~1..topic >out &&
git update-ref --stdin <out &&
git checkout topic &&
@@ -279,7 +279,7 @@ test_expect_success 'rename same file identically, then add file to old dir' '
GIT_TRACE2_PERF="$(pwd)/trace.output" &&
export GIT_TRACE2_PERF &&
- git replay --onto HEAD upstream~1 topic >out &&
+ git replay --onto HEAD upstream~1..topic >out &&
git update-ref --stdin <out &&
git checkout topic &&
@@ -357,7 +357,7 @@ test_expect_success 'cached dir rename does not prevent noticing later conflict'
GIT_TRACE2_PERF="$(pwd)/trace.output" &&
export GIT_TRACE2_PERF &&
- test_must_fail git replay --onto HEAD upstream~1 topic >output &&
+ test_must_fail git replay --onto HEAD upstream~1..topic >output &&
grep region_enter.*diffcore_rename trace.output >calls &&
test_line_count = 2 calls
@@ -456,7 +456,7 @@ test_expect_success 'dir rename unneeded, then add new file to old dir' '
GIT_TRACE2_PERF="$(pwd)/trace.output" &&
export GIT_TRACE2_PERF &&
- git replay --onto HEAD upstream~1 topic >out &&
+ git replay --onto HEAD upstream~1..topic >out &&
git update-ref --stdin <out &&
git checkout topic &&
@@ -523,7 +523,7 @@ test_expect_success 'dir rename unneeded, then rename existing file into old dir
GIT_TRACE2_PERF="$(pwd)/trace.output" &&
export GIT_TRACE2_PERF &&
- git replay --onto HEAD upstream~1 topic >out &&
+ git replay --onto HEAD upstream~1..topic >out &&
git update-ref --stdin <out &&
git checkout topic &&
@@ -626,7 +626,7 @@ test_expect_success 'caching renames only on upstream side, part 1' '
GIT_TRACE2_PERF="$(pwd)/trace.output" &&
export GIT_TRACE2_PERF &&
- git replay --onto HEAD upstream~1 topic >out &&
+ git replay --onto HEAD upstream~1..topic >out &&
git update-ref --stdin <out &&
git checkout topic &&
@@ -685,7 +685,7 @@ test_expect_success 'caching renames only on upstream side, part 2' '
GIT_TRACE2_PERF="$(pwd)/trace.output" &&
export GIT_TRACE2_PERF &&
- git replay --onto HEAD upstream~1 topic >out &&
+ git replay --onto HEAD upstream~1..topic >out &&
git update-ref --stdin <out &&
git checkout topic &&
--
2.42.0.496.g529a7fda40
^ permalink raw reply related
* [PATCH v6 10/14] replay: make it a minimal server side command
From: Christian Couder @ 2023-11-02 13:51 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Patrick Steinhardt, Johannes Schindelin,
Elijah Newren, John Cai, Derrick Stolee, Phillip Wood, Calvin Wan,
Toon Claes, Dragan Simic, Linus Arver, Christian Couder
In-Reply-To: <20231102135151.843758-1-christian.couder@gmail.com>
From: Elijah Newren <newren@gmail.com>
We want this command to be a minimal command that just does server side
picking of commits, displaying the results on stdout for higher level
scripts to consume.
So let's simplify it:
* remove the worktree and index reading/writing,
* remove the ref (and reflog) updating,
* remove the assumptions tying us to HEAD, since (a) this is not a
rebase and (b) we want to be able to pick commits in a bare repo,
i.e. to/from branches that are not checked out and not the main
branch,
* remove unneeded includes,
* handle rebasing multiple branches by printing on stdout the update
ref commands that should be performed.
The output can be piped into `git update-ref --stdin` for the ref
updates to happen.
In the future to make it easier for users to use this command
directly maybe an option can be added to automatically pipe its output
into `git update-ref`.
Co-authored-by: Christian Couder <chriscool@tuxfamily.org>
Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
---
Documentation/git-replay.txt | 5 +-
builtin/replay.c | 78 ++++++++----------------
t/t3650-replay-basics.sh | 19 +++++-
t/t6429-merge-sequence-rename-caching.sh | 39 +++++++-----
4 files changed, 72 insertions(+), 69 deletions(-)
diff --git a/Documentation/git-replay.txt b/Documentation/git-replay.txt
index 44bf584fed..4c852ff3bd 100644
--- a/Documentation/git-replay.txt
+++ b/Documentation/git-replay.txt
@@ -14,7 +14,10 @@ SYNOPSIS
DESCRIPTION
-----------
-Takes a range of commits and replays them onto a new location.
+Takes a range of commits and replays them onto a new location. Leaves
+the working tree and the index untouched, and updates no
+references. The output of this command is meant to be used as input to
+`git update-ref --stdin`, which would update the relevant branches.
THIS COMMAND IS EXPERIMENTAL. THE BEHAVIOR MAY CHANGE.
diff --git a/builtin/replay.c b/builtin/replay.c
index 9331f5c6ec..7e3ebac3db 100644
--- a/builtin/replay.c
+++ b/builtin/replay.c
@@ -6,11 +6,7 @@
#include "git-compat-util.h"
#include "builtin.h"
-#include "cache-tree.h"
-#include "commit.h"
#include "environment.h"
-#include "gettext.h"
-#include "hash.h"
#include "hex.h"
#include "lockfile.h"
#include "merge-ort.h"
@@ -18,8 +14,6 @@
#include "parse-options.h"
#include "refs.h"
#include "revision.h"
-#include "sequencer.h"
-#include "setup.h"
#include "strvec.h"
#include <oidset.h>
#include <tree.h>
@@ -102,6 +96,7 @@ static struct commit *pick_regular_commit(struct commit *pickme,
pickme_tree = repo_get_commit_tree(the_repository, pickme);
base_tree = repo_get_commit_tree(the_repository, base);
+ merge_opt->branch1 = short_commit_name(last_commit);
merge_opt->branch2 = short_commit_name(pickme);
merge_opt->ancestor = xstrfmt("parent of %s", merge_opt->branch2);
@@ -122,15 +117,12 @@ int cmd_replay(int argc, const char **argv, const char *prefix)
{
struct commit *onto;
const char *onto_name = NULL;
- struct commit *last_commit = NULL, *last_picked_commit = NULL;
- struct lock_file lock = LOCK_INIT;
+ struct commit *last_commit = NULL;
struct strvec rev_walk_args = STRVEC_INIT;
struct rev_info revs;
struct commit *commit;
struct merge_options merge_opt;
- struct tree *head_tree;
struct merge_result result;
- struct strbuf reflog_msg = STRBUF_INIT;
struct strbuf branch_name = STRBUF_INIT;
int i, ret = 0;
@@ -161,10 +153,6 @@ int cmd_replay(int argc, const char **argv, const char *prefix)
onto = peel_committish(onto_name);
strbuf_addf(&branch_name, "refs/heads/%s", argv[2]);
- repo_hold_locked_index(the_repository, &lock, LOCK_DIE_ON_ERROR);
- if (repo_read_index(the_repository) < 0)
- BUG("Could not read index");
-
repo_init_revisions(the_repository, &revs, prefix);
strvec_pushl(&rev_walk_args, "", argv[2], "--not", argv[1], NULL);
@@ -203,58 +191,44 @@ int cmd_replay(int argc, const char **argv, const char *prefix)
init_merge_options(&merge_opt, the_repository);
memset(&result, 0, sizeof(result));
merge_opt.show_rename_progress = 0;
- merge_opt.branch1 = "HEAD";
- head_tree = repo_get_commit_tree(the_repository, onto);
- result.tree = head_tree;
+ result.tree = repo_get_commit_tree(the_repository, onto);
last_commit = onto;
while ((commit = get_revision(&revs))) {
- struct commit *pick;
+ const struct name_decoration *decoration;
if (!commit->parents)
die(_("replaying down to root commit is not supported yet!"));
if (commit->parents->next)
die(_("replaying merge commits is not supported yet!"));
- pick = pick_regular_commit(commit, last_commit, &merge_opt, &result);
- if (!pick)
+ last_commit = pick_regular_commit(commit, last_commit, &merge_opt, &result);
+ if (!last_commit)
break;
- last_commit = pick;
- last_picked_commit = commit;
+
+ decoration = get_name_decoration(&commit->object);
+ if (!decoration)
+ continue;
+
+ while (decoration) {
+ if (decoration->type == DECORATION_REF_LOCAL) {
+ printf("update %s %s %s\n",
+ decoration->name,
+ oid_to_hex(&last_commit->object.oid),
+ oid_to_hex(&commit->object.oid));
+ }
+ decoration = decoration->next;
+ }
}
merge_finalize(&merge_opt, &result);
+ ret = result.clean;
- if (result.clean < 0)
- exit(128);
-
- if (result.clean) {
- strbuf_addf(&reflog_msg, "finish rebase %s onto %s",
- oid_to_hex(&last_picked_commit->object.oid),
- oid_to_hex(&last_commit->object.oid));
- if (update_ref(reflog_msg.buf, branch_name.buf,
- &last_commit->object.oid,
- &last_picked_commit->object.oid,
- REF_NO_DEREF, UPDATE_REFS_MSG_ON_ERR)) {
- error(_("could not update %s"), argv[2]);
- die("Failed to update %s", argv[2]);
- }
- if (create_symref("HEAD", branch_name.buf, reflog_msg.buf) < 0)
- die(_("unable to update HEAD"));
- } else {
- strbuf_addf(&reflog_msg, "rebase progress up to %s",
- oid_to_hex(&last_picked_commit->object.oid));
- if (update_ref(reflog_msg.buf, "HEAD",
- &last_commit->object.oid,
- &onto->object.oid,
- REF_NO_DEREF, UPDATE_REFS_MSG_ON_ERR)) {
- error(_("could not update %s"), argv[2]);
- die("Failed to update %s", argv[2]);
- }
- }
- ret = (result.clean == 0);
cleanup:
- strbuf_release(&reflog_msg);
strbuf_release(&branch_name);
release_revisions(&revs);
- return ret;
+
+ /* Return */
+ if (ret < 0)
+ exit(128);
+ return ret ? 0 : 1;
}
diff --git a/t/t3650-replay-basics.sh b/t/t3650-replay-basics.sh
index b5b9f9ade2..3567c98362 100755
--- a/t/t3650-replay-basics.sh
+++ b/t/t3650-replay-basics.sh
@@ -47,12 +47,29 @@ test_expect_success 'setup' '
test_commit C.conflict C.t conflict
'
+test_expect_success 'setup bare' '
+ git clone --bare . bare
+'
+
test_expect_success 'using replay to rebase two branches, one on top of other' '
git replay --onto main topic1 topic2 >result &&
+ test_line_count = 1 result &&
+
git log --format=%s $(cut -f 3 -d " " result) >actual &&
test_write_lines E D M L B A >expect &&
- test_cmp expect actual
+ test_cmp expect actual &&
+
+ printf "update refs/heads/topic2 " >expect &&
+ printf "%s " $(cut -f 3 -d " " result) >>expect &&
+ git rev-parse topic2 >>expect &&
+
+ test_cmp expect result
+'
+
+test_expect_success 'using replay on bare repo to rebase two branches, one on top of other' '
+ git -C bare replay --onto main topic1 topic2 >result-bare &&
+ test_cmp expect result-bare
'
test_done
diff --git a/t/t6429-merge-sequence-rename-caching.sh b/t/t6429-merge-sequence-rename-caching.sh
index 7670b72008..099aefeffc 100755
--- a/t/t6429-merge-sequence-rename-caching.sh
+++ b/t/t6429-merge-sequence-rename-caching.sh
@@ -71,8 +71,9 @@ test_expect_success 'caching renames does not preclude finding new ones' '
git switch upstream &&
- git replay --onto HEAD upstream~1 topic &&
- git reset --hard topic &&
+ git replay --onto HEAD upstream~1 topic >out &&
+ git update-ref --stdin <out &&
+ git checkout topic &&
git ls-files >tracked-files &&
test_line_count = 2 tracked-files &&
@@ -140,7 +141,9 @@ test_expect_success 'cherry-pick both a commit and its immediate revert' '
GIT_TRACE2_PERF="$(pwd)/trace.output" &&
export GIT_TRACE2_PERF &&
- git replay --onto HEAD upstream~1 topic &&
+ git replay --onto HEAD upstream~1 topic >out &&
+ git update-ref --stdin <out &&
+ git checkout topic &&
grep region_enter.*diffcore_rename trace.output >calls &&
test_line_count = 1 calls
@@ -198,8 +201,9 @@ test_expect_success 'rename same file identically, then reintroduce it' '
GIT_TRACE2_PERF="$(pwd)/trace.output" &&
export GIT_TRACE2_PERF &&
- git replay --onto HEAD upstream~1 topic &&
- git reset --hard topic &&
+ git replay --onto HEAD upstream~1 topic >out &&
+ git update-ref --stdin <out &&
+ git checkout topic &&
git ls-files >tracked &&
test_line_count = 2 tracked &&
@@ -275,8 +279,9 @@ test_expect_success 'rename same file identically, then add file to old dir' '
GIT_TRACE2_PERF="$(pwd)/trace.output" &&
export GIT_TRACE2_PERF &&
- git replay --onto HEAD upstream~1 topic &&
- git reset --hard topic &&
+ git replay --onto HEAD upstream~1 topic >out &&
+ git update-ref --stdin <out &&
+ git checkout topic &&
git ls-files >tracked &&
test_line_count = 4 tracked &&
@@ -451,8 +456,9 @@ test_expect_success 'dir rename unneeded, then add new file to old dir' '
GIT_TRACE2_PERF="$(pwd)/trace.output" &&
export GIT_TRACE2_PERF &&
- git replay --onto HEAD upstream~1 topic &&
- git reset --hard topic &&
+ git replay --onto HEAD upstream~1 topic >out &&
+ git update-ref --stdin <out &&
+ git checkout topic &&
grep region_enter.*diffcore_rename trace.output >calls &&
test_line_count = 2 calls &&
@@ -517,8 +523,9 @@ test_expect_success 'dir rename unneeded, then rename existing file into old dir
GIT_TRACE2_PERF="$(pwd)/trace.output" &&
export GIT_TRACE2_PERF &&
- git replay --onto HEAD upstream~1 topic &&
- git reset --hard topic &&
+ git replay --onto HEAD upstream~1 topic >out &&
+ git update-ref --stdin <out &&
+ git checkout topic &&
grep region_enter.*diffcore_rename trace.output >calls &&
test_line_count = 3 calls &&
@@ -619,8 +626,9 @@ test_expect_success 'caching renames only on upstream side, part 1' '
GIT_TRACE2_PERF="$(pwd)/trace.output" &&
export GIT_TRACE2_PERF &&
- git replay --onto HEAD upstream~1 topic &&
- git reset --hard topic &&
+ git replay --onto HEAD upstream~1 topic >out &&
+ git update-ref --stdin <out &&
+ git checkout topic &&
grep region_enter.*diffcore_rename trace.output >calls &&
test_line_count = 1 calls &&
@@ -677,8 +685,9 @@ test_expect_success 'caching renames only on upstream side, part 2' '
GIT_TRACE2_PERF="$(pwd)/trace.output" &&
export GIT_TRACE2_PERF &&
- git replay --onto HEAD upstream~1 topic &&
- git reset --hard topic &&
+ git replay --onto HEAD upstream~1 topic >out &&
+ git update-ref --stdin <out &&
+ git checkout topic &&
grep region_enter.*diffcore_rename trace.output >calls &&
test_line_count = 2 calls &&
--
2.42.0.496.g529a7fda40
^ permalink raw reply related
* [PATCH v6 09/14] replay: remove HEAD related sanity check
From: Christian Couder @ 2023-11-02 13:51 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Patrick Steinhardt, Johannes Schindelin,
Elijah Newren, John Cai, Derrick Stolee, Phillip Wood, Calvin Wan,
Toon Claes, Dragan Simic, Linus Arver, Christian Couder
In-Reply-To: <20231102135151.843758-1-christian.couder@gmail.com>
From: Elijah Newren <newren@gmail.com>
We want replay to be a command that can be used on the server side on
any branch, not just the current one, so we are going to stop updating
HEAD in a future commit.
A "sanity check" that makes sure we are replaying the current branch
doesn't make sense anymore. Let's remove it.
Co-authored-by: Christian Couder <chriscool@tuxfamily.org>
Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
---
builtin/replay.c | 8 +-------
t/t3650-replay-basics.sh | 2 --
2 files changed, 1 insertion(+), 9 deletions(-)
diff --git a/builtin/replay.c b/builtin/replay.c
index 74680b0c8f..9331f5c6ec 100644
--- a/builtin/replay.c
+++ b/builtin/replay.c
@@ -123,7 +123,6 @@ int cmd_replay(int argc, const char **argv, const char *prefix)
struct commit *onto;
const char *onto_name = NULL;
struct commit *last_commit = NULL, *last_picked_commit = NULL;
- struct object_id head;
struct lock_file lock = LOCK_INIT;
struct strvec rev_walk_args = STRVEC_INIT;
struct rev_info revs;
@@ -162,11 +161,6 @@ int cmd_replay(int argc, const char **argv, const char *prefix)
onto = peel_committish(onto_name);
strbuf_addf(&branch_name, "refs/heads/%s", argv[2]);
- /* Sanity check */
- if (repo_get_oid(the_repository, "HEAD", &head))
- die(_("Cannot read HEAD"));
- assert(oideq(&onto->object.oid, &head));
-
repo_hold_locked_index(the_repository, &lock, LOCK_DIE_ON_ERROR);
if (repo_read_index(the_repository) < 0)
BUG("Could not read index");
@@ -251,7 +245,7 @@ int cmd_replay(int argc, const char **argv, const char *prefix)
oid_to_hex(&last_picked_commit->object.oid));
if (update_ref(reflog_msg.buf, "HEAD",
&last_commit->object.oid,
- &head,
+ &onto->object.oid,
REF_NO_DEREF, UPDATE_REFS_MSG_ON_ERR)) {
error(_("could not update %s"), argv[2]);
die("Failed to update %s", argv[2]);
diff --git a/t/t3650-replay-basics.sh b/t/t3650-replay-basics.sh
index 36c1b5082a..b5b9f9ade2 100755
--- a/t/t3650-replay-basics.sh
+++ b/t/t3650-replay-basics.sh
@@ -48,8 +48,6 @@ test_expect_success 'setup' '
'
test_expect_success 'using replay to rebase two branches, one on top of other' '
- git switch main &&
-
git replay --onto main topic1 topic2 >result &&
git log --format=%s $(cut -f 3 -d " " result) >actual &&
--
2.42.0.496.g529a7fda40
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox