Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions Documentation/RelNotes/2.56.0.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,16 @@ UI, Workflows & Features
'CHERRY_PICK_HEAD' ref. A test has also been added to ensure this
behavior holds even when the operation stops for conflicts.

* The 'git imap-send' command has been taught to take the '--draft'
option to mark uploaded messages as drafts, which helps some email
clients render them properly for editing and sending.

* The git rev-list command has been augmented with a '--missing-only'
option that filters the output to only show missing objects,
stripping the leading '?' character and suppressing present objects,
which is useful when used in combination with '--missing=print' or
'--missing=print-info'.


Performance, Internal Implementation, Development Support etc.
--------------------------------------------------------------
Expand Down Expand Up @@ -528,6 +538,14 @@ Performance, Internal Implementation, Development Support etc.
the cumulative time spent downloading external packs and the number
of advertised URIs without emitting a separate event per pack.

* CGI helper scripts used by HTTP-related test scripts have been updated
to use atomic filesystem operations, preventing race conditions when
Apache handles concurrent requests.

* "git maintenance" triggered "rerere gc" in unappropriate times and
interfered with "git rebase" etc. too much. The conditions "rerere
gc" gets triggered have been tweaked.


Fixes since v2.55
-----------------
Expand Down Expand Up @@ -859,6 +877,12 @@ Fixes since v2.55
expression syntax that breaks on older Perl versions.
(merge 8a631963a9 ta/lint-gitlink-older-perl-fix later to maint).

* The autostash fallback in 'git checkout -m' has been refined to only
retry when there are local changes. Additionally, a blank line now
visually separates autostash conflict advice from the subsequent
branch-switch message.
(merge 2ba77ea828 hn/checkout-m-autostash-refine later to maint).

* Other code cleanup, docfix, build fix, etc.
(merge 026636128f ss/submittingpatches-typofix later to maint).
(merge d2af22cc21 jc/rerere-doc-typofix later to maint).
Expand Down
8 changes: 4 additions & 4 deletions Documentation/config/maintenance.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -122,10 +122,10 @@ maintenance.rerere-gc.auto::
This integer config option controls how often the `rerere-gc` task
should be run as part of `git maintenance run --auto`. If zero, then
the `rerere-gc` task will not run with the `--auto` option. A negative
value will force the task to run every time. Otherwise, any positive
value implies the command will run when the "rr-cache" directory exists
and has at least one entry, regardless of whether it is stale or not.
This heuristic may be refined in the future. The default value is 1.
value will force the task to run every time. Otherwise, a positive
value implies the command should run when the estimated number of stale
entries that would be pruned is greater than or equal to the configured
value. The default value is 512.

maintenance.worktree-prune.auto::
This integer config option controls how often the `worktree-prune` task
Expand Down
9 changes: 8 additions & 1 deletion Documentation/git-imap-send.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ git-imap-send - Send a collection of patches from stdin to an IMAP folder
SYNOPSIS
--------
[synopsis]
git imap-send [-v] [-q] [--[no-]curl] [(--folder|-f) <folder>]
git imap-send [-v] [-q] [--[no-]curl] [--[no-]draft] [(--folder|-f) <folder>]
git imap-send --list


Expand Down Expand Up @@ -55,6 +55,13 @@ OPTIONS
using libcurl. Ignored if Git was built with the NO_OPENSSL option
set.

`--draft`::
`--no-draft`::
Mark uploaded messages with the IMAP `\Draft` flag. The default is `--no-draft`.
+
With libcurl, `--draft` requires version 8.13.0 or later.
Older libcurl still uploads the message but cannot set the flag.

`--list`::
Run the IMAP LIST command to output a list of all the folders present.

Expand Down
9 changes: 9 additions & 0 deletions Documentation/git-stash.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,15 @@ include::includes/cmd-config-section-all.adoc[]
:git-stash: 1
include::config/stash.adoc[]

EXIT STATUS
-----------
The `git stash` subcommands exit with status 0 on success. The
subcommands that apply a stash entry, i.e. `apply`, `pop` and `branch`,
exit with status 1 when applying the stash entry resulted in conflicts,
in which case the stash entry is left in place, and with a non-zero
status other than 1 when they fail for other reasons.
SEE ALSO
--------
Expand Down
13 changes: 13 additions & 0 deletions Documentation/rev-list-options.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -1083,6 +1083,19 @@ If some tips passed to the traversal are missing, they will be
considered as missing too, and the traversal will ignore them. In case
we cannot get their Object ID though, an error will be raised.

`--missing-only`::
When used together with `--missing=print` or `--missing=print-info`,
suppress all output for present objects and print only the missing
ones. The selected `--missing=` format is preserved (so
`--missing=print-info` still emits `path=` / `type=` fields), but the
leading ``?'' prefix used by the non-`-z` forms is omitted. This is
useful for scripting, as a simpler and faster alternative to
post-processing the output of `--missing=print`.
+
This option is incompatible with `--count` and `--disk-usage`.
It is an error to use `--missing-only` without `--missing=print` or
`--missing=print-info`.

`--exclude-promisor-objects`::
(For internal use only.) Prefilter object traversal at
promisor boundary. This is used with partial clone. This is
Expand Down
15 changes: 9 additions & 6 deletions builtin/checkout.c
Original file line number Diff line number Diff line change
Expand Up @@ -1166,6 +1166,7 @@ static int switch_branches(const struct checkout_opts *opts,
int flag, writeout_error = 0;
int do_merge = 1;
int created_autostash = 0;
enum stash_apply_result autostash_res = STASH_APPLY_CLEAN;
struct strbuf old_commit_shortname = STRBUF_INIT;
struct strbuf autostash_msg = STRBUF_INIT;
const char *stash_label_base = NULL;
Expand Down Expand Up @@ -1237,12 +1238,12 @@ static int switch_branches(const struct checkout_opts *opts,
git_config_push_parameter(cfg.buf);
strbuf_release(&cfg);
}
apply_autostash_ref(the_repository,
"CHECKOUT_AUTOSTASH_HEAD",
new_branch_info->name,
"local",
stash_label_base,
autostash_msg.buf);
autostash_res = apply_autostash_ref(the_repository,
"CHECKOUT_AUTOSTASH_HEAD",
new_branch_info->name,
"local",
stash_label_base,
autostash_msg.buf);
}
if (ret) {
branch_info_release(&old_branch_info);
Expand All @@ -1255,6 +1256,8 @@ static int switch_branches(const struct checkout_opts *opts,
if (!opts->quiet && !old_branch_info.path && old_branch_info.commit && new_branch_info->commit != old_branch_info.commit)
orphaned_commit_warning(old_branch_info.commit, new_branch_info->commit);

if (autostash_res == STASH_APPLY_CONFLICT && !opts->quiet)
fputc('\n', stderr);
update_refs_for_switch(opts, &old_branch_info, new_branch_info);

if (created_autostash) {
Expand Down
28 changes: 6 additions & 22 deletions builtin/gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -396,31 +396,15 @@ static int maintenance_task_rerere_gc(struct maintenance_run_opts *opts UNUSED,

static int rerere_gc_condition(struct gc_config *cfg UNUSED)
{
struct strbuf path = STRBUF_INIT;
int should_gc = 0, limit = 1;
DIR *dir = NULL;
int limit = 512;

repo_config_get_int(the_repository, "maintenance.rerere-gc.auto", &limit);
if (limit <= 0) {
should_gc = limit < 0;
goto out;
}

/*
* We skip garbage collection in case we either have no "rr-cache"
* directory or when it doesn't contain at least one entry.
*/
repo_git_path_replace(the_repository, &path, "rr-cache");
dir = opendir(path.buf);
if (!dir)
goto out;
should_gc = !!readdir_skip_dot_and_dotdot(dir);
if (!limit)
return 0; /* never prune */
if (limit < 0)
return 1; /* always prune */

out:
strbuf_release(&path);
if (dir)
closedir(dir);
return should_gc;
return rerere_gc_needed(the_repository, (size_t)limit);
}

#define OPTIMIZE_FIELDS_FROM_GC_CONFIG(cfg, aggressive) \
Expand Down
42 changes: 37 additions & 5 deletions builtin/rev-list.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,13 @@ enum missing_action {
MA_ALLOW_PROMISOR, /* silently allow all missing PROMISOR objects */
};
static enum missing_action arg_missing_action;
static int arg_missing_only;

static inline int should_collect_missing(void)
{
return arg_missing_action == MA_PRINT ||
arg_missing_action == MA_PRINT_INFO;
}

/* display only the oid of each object encountered */
static int arg_show_object_names = 1;
Expand Down Expand Up @@ -156,7 +163,14 @@ static void print_missing_object(struct missing_objects_map_entry *entry,
{
struct strbuf sb = STRBUF_INIT;

if (line_term)
/*
* --missing-only filters present objects out of the walk output.
* It still uses the selected --missing= format for missing ones,
* except the human "?" prefix is omitted (script-friendly OIDs).
*/
if (arg_missing_only && line_term)
printf("%s", oid_to_hex(&entry->entry.oid));
else if (line_term)
printf("?%s", oid_to_hex(&entry->entry.oid));
else
printf("%s%cmissing=yes", oid_to_hex(&entry->entry.oid),
Expand Down Expand Up @@ -246,6 +260,11 @@ static void show_commit(struct commit *commit, void *data)
return;
}

if (arg_missing_only) {
finish_commit(commit);
return;
}

if (show_disk_usage)
total_disk_usage += get_object_disk_usage(&commit->object);

Expand Down Expand Up @@ -384,6 +403,8 @@ static void show_object(struct object *obj, const char *name, void *cb_data)
if (finish_object(obj, name, cb_data))
return;
display_progress(progress, ++progress_counter);
if (arg_missing_only)
return;
if (show_disk_usage)
total_disk_usage += get_object_disk_usage(obj);
if (info->flags & REV_LIST_QUIET)
Expand Down Expand Up @@ -750,12 +771,17 @@ int cmd_rev_list(int argc,
revs.exclude_promisor_objects = 1;
} else if (skip_prefix(arg, "--missing=", &arg)) {
parse_missing_action_value(repo, arg);
} else if (!strcmp(arg, "--missing-only")) {
arg_missing_only = 1;
} else if (!strcmp(arg, "-z")) {
line_term = '\0';
info_term = '\0';
}
}

if (arg_missing_only && !should_collect_missing())
die(_("--missing-only requires --missing=print or --missing=print-info"));

die_for_incompatible_opt2(revs.exclude_promisor_objects,
"--exclude_promisor_objects",
arg_missing_action, "--missing");
Expand Down Expand Up @@ -865,6 +891,9 @@ int cmd_rev_list(int argc,
continue;
}

if (!strcmp(arg, "--missing-only"))
continue;

usage(rev_list_usage);

}
Expand Down Expand Up @@ -911,6 +940,11 @@ int cmd_rev_list(int argc,
(revs.left_right || revs.cherry_mark))
die(_("marked counting and '%s' cannot be used together"), "--objects");

die_for_incompatible_opt2(arg_missing_only, "--missing-only",
revs.count, "--count");
die_for_incompatible_opt2(arg_missing_only, "--missing-only",
show_disk_usage, "--disk-usage");

save_commit_buffer = (revs.verbose_header ||
revs.grep_filter.pattern_list ||
revs.grep_filter.header_list);
Expand Down Expand Up @@ -968,8 +1002,7 @@ int cmd_rev_list(int argc,

if (arg_print_omitted)
oidset_init(&omitted_objects, DEFAULT_OIDSET_SIZE);
if (arg_missing_action == MA_PRINT ||
arg_missing_action == MA_PRINT_INFO) {
if (should_collect_missing()) {
struct oidset_iter iter;
struct object_id *oid;

Expand All @@ -995,8 +1028,7 @@ int cmd_rev_list(int argc,
printf("~%s\n", oid_to_hex(oid));
oidset_clear(&omitted_objects);
}
if (arg_missing_action == MA_PRINT ||
arg_missing_action == MA_PRINT_INFO) {
if (should_collect_missing()) {
struct missing_objects_map_entry *entry;
struct oidmap_iter iter;

Expand Down
33 changes: 24 additions & 9 deletions builtin/stash.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "object-name.h"
#include "parse-options.h"
#include "refs.h"
#include "stash.h"
#include "lockfile.h"
#include "cache-tree.h"
#include "unpack-trees.h"
Expand Down Expand Up @@ -640,10 +641,12 @@ static void unstage_changes_unless_new(struct object_id *orig_tree)
die(_("could not write index"));
}

static int do_apply_stash(const char *prefix, struct stash_info *info,
int index, int quiet,
const char *label_ours, const char *label_theirs,
const char *label_base)
static enum stash_apply_result do_apply_stash(const char *prefix,
struct stash_info *info,
int index, int quiet,
const char *label_ours,
const char *label_theirs,
const char *label_base)
{
int clean, ret;
int has_index = index;
Expand Down Expand Up @@ -717,8 +720,8 @@ static int do_apply_stash(const char *prefix, struct stash_info *info,

/*
* If 'clean' >= 0, reverse the value for 'ret' so 'ret' is 0 when the
* merge was clean, and nonzero if the merge was unclean or encountered
* an error.
* merge was clean, and 1 if the merge was unclean or a negative value
* if it encountered an error.
*/
ret = clean >= 0 ? !clean : clean;

Expand Down Expand Up @@ -2492,10 +2495,22 @@ int cmd_stash(int argc,
strbuf_addf(&stash_index_path, "%s.stash.%" PRIuMAX, index_file,
(uintmax_t)pid);

if (fn)
return !!fn(argc, argv, prefix, repo);
else if (!argc)
if (fn) {
ret = fn(argc, argv, prefix, repo);

/*
* The subcommand implementations return 0 on success, a
* negative value on failure, and STASH_APPLY_CONFLICT
* when applying a stash entry resulted in conflicts.
* Map failures to 128, the status die() uses, so that
* exit status 1 unambiguously indicates conflicts.
*/
if (ret < 0)
return 128;
return ret;
} else if (!argc) {
return !!push_stash_unassumed(0, NULL, prefix, repo);
}

/* Assume 'stash push' */
strvec_push(&args, "push");
Expand Down
8 changes: 8 additions & 0 deletions git-curl-compat.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,4 +67,12 @@
#define GIT_CURL_HAVE_CURLOPT_TCP_KEEPCNT
#endif

/**
* CURLOPT_UPLOAD_FLAGS and CURLULFLAG_* were added in 8.13.0,
* released in April 2025.
*/
#if LIBCURL_VERSION_NUM >= 0x080D00
#define GIT_CURL_HAVE_CURLOPT_UPLOAD_FLAGS
#endif

#endif
Loading