aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/RelNotes/2.26.0.txt53
-rw-r--r--Documentation/gitcore-tutorial.txt2
-rwxr-xr-xGIT-VERSION-GEN2
l---------RelNotes2
-rw-r--r--builtin/checkout.c2
-rw-r--r--builtin/commit.c1
-rw-r--r--contrib/credential/netrc/.gitignore1
-rw-r--r--contrib/credential/netrc/Makefile26
-rwxr-xr-xcontrib/credential/netrc/git-credential-netrc.perl (renamed from contrib/credential/netrc/git-credential-netrc)2
-rw-r--r--object-store.h2
-rw-r--r--run-command.c3
-rw-r--r--sha1-file.c38
-rw-r--r--string-list.h6
-rwxr-xr-xt/t2070-restore.sh17
-rwxr-xr-xt/t5702-protocol-v2.sh12
-rwxr-xr-xt/t7500-commit-template-squash-signoff.sh9
-rw-r--r--transport.c2
-rw-r--r--unpack-trees.c32
18 files changed, 166 insertions, 46 deletions
diff --git a/Documentation/RelNotes/2.26.0.txt b/Documentation/RelNotes/2.26.0.txt
new file mode 100644
index 0000000000..5553c1f4e6
--- /dev/null
+++ b/Documentation/RelNotes/2.26.0.txt
@@ -0,0 +1,53 @@
+Git 2.26 Release Notes
+======================
+
+Updates since v2.25
+-------------------
+
+UI, Workflows & Features
+
+ * Sample credential helper for using .netrc has been updated to work
+ out of the box.
+
+
+Performance, Internal Implementation, Development Support etc.
+
+
+Fixes since v2.25
+-----------------
+
+ * "git commit" gives output similar to "git status" when there is
+ nothing to commit, but without honoring the advise.statusHints
+ configuration variable, which has been corrected.
+ (merge 5c4f55f1f6 hw/commit-advise-while-rejecting later to maint).
+
+ * has_object_file() said "no" given an object registered to the
+ system via pretend_object_file(), making it inconsistent with
+ read_object_file(), causing lazy fetch to attempt fetching an
+ empty tree from promisor remotes.
+ (merge 9c8a294a1a jt/sha1-file-remove-oi-skip-cached later to maint).
+
+ * Complete an update to tutorial that encourages "git switch" over
+ "git checkout" that was done only half-way.
+ (merge 1a7e454dd6 hw/tutorial-favor-switch-over-checkout later to maint).
+
+ * C pedantry ;-) fix.
+ (merge 63ab08fb99 bc/run-command-nullness-after-free-fix later to maint).
+
+ * The code that tries to skip over the entries for the paths in a
+ single directory using the cache-tree was not careful enough
+ against corrupt index file.
+ (merge 573117dfa5 es/unpack-trees-oob-fix later to maint).
+
+ * Reduce unnecessary round-trip when running "ls-remote" over the
+ stateless RPC mechanism.
+ (merge 4d8cab95cc jk/no-flush-upon-disconnecting-slrpc-transport later to maint).
+
+ * "git restore --staged" did not correctly update the cache-tree
+ structure, resulting in bogus trees to be written afterwards, which
+ has been corrected.
+ (merge e701bab3e9 nd/switch-and-restore later to maint).
+
+ * Other code cleanup, docfix, build fix, etc.
+ (merge 26f924d50e en/simplify-check-updates-in-unpack-trees later to maint).
+ (merge 065027ee1a en/string-list-can-be-custom-sorted later to maint).
diff --git a/Documentation/gitcore-tutorial.txt b/Documentation/gitcore-tutorial.txt
index f880d21dfb..c0b95256cc 100644
--- a/Documentation/gitcore-tutorial.txt
+++ b/Documentation/gitcore-tutorial.txt
@@ -751,7 +751,7 @@ to it.
================================================
If you make the decision to start your new branch at some
other point in the history than the current `HEAD`, you can do so by
-just telling 'git checkout' what the base of the checkout would be.
+just telling 'git switch' what the base of the checkout would be.
In other words, if you have an earlier tag or branch, you'd just do
------------
diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN
index 2b7f62b8bf..616d5a6404 100755
--- a/GIT-VERSION-GEN
+++ b/GIT-VERSION-GEN
@@ -1,7 +1,7 @@
#!/bin/sh
GVF=GIT-VERSION-FILE
-DEF_VER=v2.25.0
+DEF_VER=v2.25.GIT
LF='
'
diff --git a/RelNotes b/RelNotes
index 091dd024b3..370269d8df 120000
--- a/RelNotes
+++ b/RelNotes
@@ -1 +1 @@
-Documentation/RelNotes/2.25.0.txt \ No newline at end of file
+Documentation/RelNotes/2.26.0.txt \ No newline at end of file
diff --git a/builtin/checkout.c b/builtin/checkout.c
index b52c490c8f..18ef5fb975 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -524,6 +524,8 @@ static int checkout_paths(const struct checkout_opts *opts,
/* Now we are committed to check them out */
if (opts->checkout_worktree)
errs |= checkout_worktree(opts);
+ else
+ remove_marked_cache_entries(&the_index, 1);
/*
* Allow updating the index when checking out from the index.
diff --git a/builtin/commit.c b/builtin/commit.c
index aa1332308a..646e84547d 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -964,6 +964,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
*/
if (!committable && whence != FROM_MERGE && !allow_empty &&
!(amend && is_a_merge(current_head))) {
+ s->hints = advice_status_hints;
s->display_comment_prefix = old_display_comment_prefix;
run_status(stdout, index_file, prefix, 0, s);
if (amend)
diff --git a/contrib/credential/netrc/.gitignore b/contrib/credential/netrc/.gitignore
new file mode 100644
index 0000000000..d41cdde84b
--- /dev/null
+++ b/contrib/credential/netrc/.gitignore
@@ -0,0 +1 @@
+git-credential-netrc
diff --git a/contrib/credential/netrc/Makefile b/contrib/credential/netrc/Makefile
index 6174e3bb83..c284fb8ac4 100644
--- a/contrib/credential/netrc/Makefile
+++ b/contrib/credential/netrc/Makefile
@@ -1,8 +1,30 @@
# The default target of this Makefile is...
all::
-test:
+SCRIPT_PERL = git-credential-netrc.perl
+GIT_ROOT_DIR = ../../..
+HERE = contrib/credential/netrc
+
+SCRIPT_PERL_FULL = $(patsubst %,$(HERE)/%,$(SCRIPT_PERL))
+
+all:: build
+
+build:
+ $(MAKE) -C $(GIT_ROOT_DIR) SCRIPT_PERL="$(SCRIPT_PERL_FULL)" \
+ build-perl-script
+
+install: build
+ $(MAKE) -C $(GIT_ROOT_DIR) SCRIPT_PERL="$(SCRIPT_PERL_FULL)" \
+ install-perl-script
+
+clean:
+ $(MAKE) -C $(GIT_ROOT_DIR) SCRIPT_PERL="$(SCRIPT_PERL_FULL)" \
+ clean-perl-script
+
+test: build
./t-git-credential-netrc.sh
-testverbose:
+testverbose: build
./t-git-credential-netrc.sh -d -v
+
+.PHONY: all build install clean test testverbose
diff --git a/contrib/credential/netrc/git-credential-netrc b/contrib/credential/netrc/git-credential-netrc.perl
index ebfc123ec6..bc57cc6588 100755
--- a/contrib/credential/netrc/git-credential-netrc
+++ b/contrib/credential/netrc/git-credential-netrc.perl
@@ -423,7 +423,7 @@ sub load_config {
# load settings from git config
my $options = shift;
# set from command argument, gpg.program option, or default to gpg
- $options->{'gpg'} //= Git->repository()->config('gpg.program')
+ $options->{'gpg'} //= Git::config('gpg.program')
// 'gpg';
log_verbose("using $options{'gpg'} for GPG operations");
}
diff --git a/object-store.h b/object-store.h
index 55ee639350..61b8b13e3b 100644
--- a/object-store.h
+++ b/object-store.h
@@ -292,8 +292,6 @@ struct object_info {
#define OBJECT_INFO_LOOKUP_REPLACE 1
/* Allow reading from a loose object file of unknown/bogus type */
#define OBJECT_INFO_ALLOW_UNKNOWN_TYPE 2
-/* Do not check cached storage */
-#define OBJECT_INFO_SKIP_CACHED 4
/* Do not retry packed storage after checking packed and loose storage */
#define OBJECT_INFO_QUICK 8
/* Do not check loose object */
diff --git a/run-command.c b/run-command.c
index 9942f120a9..f5e1149f9b 100644
--- a/run-command.c
+++ b/run-command.c
@@ -213,8 +213,9 @@ static char *locate_in_PATH(const char *file)
static int exists_in_PATH(const char *file)
{
char *r = locate_in_PATH(file);
+ int found = r != NULL;
free(r);
- return r != NULL;
+ return found;
}
int sane_execvp(const char *file, char * const argv[])
diff --git a/sha1-file.c b/sha1-file.c
index 188de57634..03ae9ae93a 100644
--- a/sha1-file.c
+++ b/sha1-file.c
@@ -1417,6 +1417,7 @@ int oid_object_info_extended(struct repository *r, const struct object_id *oid,
struct object_info *oi, unsigned flags)
{
static struct object_info blank_oi = OBJECT_INFO_INIT;
+ struct cached_object *co;
struct pack_entry e;
int rtype;
const struct object_id *real = oid;
@@ -1431,24 +1432,22 @@ int oid_object_info_extended(struct repository *r, const struct object_id *oid,
if (!oi)
oi = &blank_oi;
- if (!(flags & OBJECT_INFO_SKIP_CACHED)) {
- struct cached_object *co = find_cached_object(real);
- if (co) {
- if (oi->typep)
- *(oi->typep) = co->type;
- if (oi->sizep)
- *(oi->sizep) = co->size;
- if (oi->disk_sizep)
- *(oi->disk_sizep) = 0;
- if (oi->delta_base_sha1)
- hashclr(oi->delta_base_sha1);
- if (oi->type_name)
- strbuf_addstr(oi->type_name, type_name(co->type));
- if (oi->contentp)
- *oi->contentp = xmemdupz(co->buf, co->size);
- oi->whence = OI_CACHED;
- return 0;
- }
+ co = find_cached_object(real);
+ if (co) {
+ if (oi->typep)
+ *(oi->typep) = co->type;
+ if (oi->sizep)
+ *(oi->sizep) = co->size;
+ if (oi->disk_sizep)
+ *(oi->disk_sizep) = 0;
+ if (oi->delta_base_sha1)
+ hashclr(oi->delta_base_sha1);
+ if (oi->type_name)
+ strbuf_addstr(oi->type_name, type_name(co->type));
+ if (oi->contentp)
+ *oi->contentp = xmemdupz(co->buf, co->size);
+ oi->whence = OI_CACHED;
+ return 0;
}
while (1) {
@@ -1932,8 +1931,7 @@ int repo_has_object_file_with_flags(struct repository *r,
{
if (!startup_info->have_repository)
return 0;
- return oid_object_info_extended(r, oid, NULL,
- flags | OBJECT_INFO_SKIP_CACHED) >= 0;
+ return oid_object_info_extended(r, oid, NULL, flags) >= 0;
}
int repo_has_object_file(struct repository *r,
diff --git a/string-list.h b/string-list.h
index 7bb0ad07e6..6c5d274126 100644
--- a/string-list.h
+++ b/string-list.h
@@ -4,7 +4,8 @@
/**
* The string_list API offers a data structure and functions to handle
* sorted and unsorted arrays of strings. A "sorted" list is one whose
- * entries are sorted by string value in `strcmp()` order.
+ * entries are sorted by string value in the order specified by the `cmp`
+ * member (`strcmp()` by default).
*
* The caller:
*
@@ -209,7 +210,8 @@ struct string_list_item *string_list_append(struct string_list *list, const char
struct string_list_item *string_list_append_nodup(struct string_list *list, char *string);
/**
- * Sort the list's entries by string value in `strcmp()` order.
+ * Sort the list's entries by string value in order specified by list->cmp
+ * (strcmp() if list->cmp is NULL).
*/
void string_list_sort(struct string_list *list);
diff --git a/t/t2070-restore.sh b/t/t2070-restore.sh
index 21c3f84459..076d0df7fc 100755
--- a/t/t2070-restore.sh
+++ b/t/t2070-restore.sh
@@ -106,4 +106,21 @@ test_expect_success 'restore --staged adds deleted intent-to-add file back to in
git diff --cached --exit-code
'
+test_expect_success 'restore --staged invalidates cache tree for deletions' '
+ test_when_finished git reset --hard &&
+ >new1 &&
+ >new2 &&
+ git add new1 new2 &&
+
+ # It is important to commit and then reset here, so that the index
+ # contains a valid cache-tree for the "both" tree.
+ git commit -m both &&
+ git reset --soft HEAD^ &&
+
+ git restore --staged new1 &&
+ git commit -m "just new2" &&
+ git rev-parse HEAD:new2 &&
+ test_must_fail git rev-parse HEAD:new1
+'
+
test_done
diff --git a/t/t5702-protocol-v2.sh b/t/t5702-protocol-v2.sh
index e73067d23f..7fd7102c87 100755
--- a/t/t5702-protocol-v2.sh
+++ b/t/t5702-protocol-v2.sh
@@ -665,6 +665,18 @@ test_expect_success 'fetch from namespaced repo respects namespaces' '
test_cmp expect actual
'
+test_expect_success 'ls-remote with v2 http sends only one POST' '
+ test_when_finished "rm -f log" &&
+
+ git ls-remote "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" >expect &&
+ GIT_TRACE_CURL="$(pwd)/log" git -c protocol.version=2 \
+ ls-remote "$HTTPD_URL/smart/http_parent" >actual &&
+ test_cmp expect actual &&
+
+ grep "Send header: POST" log >posts &&
+ test_line_count = 1 posts
+'
+
test_expect_success 'push with http:// and a config of v2 does not request v2' '
test_when_finished "rm -f log" &&
# Till v2 for push is designed, make sure that if a client has
diff --git a/t/t7500-commit-template-squash-signoff.sh b/t/t7500-commit-template-squash-signoff.sh
index 46a5cd4b73..6d19ece05d 100755
--- a/t/t7500-commit-template-squash-signoff.sh
+++ b/t/t7500-commit-template-squash-signoff.sh
@@ -382,4 +382,13 @@ test_expect_success 'check commit with unstaged rename and copy' '
)
'
+test_expect_success 'commit without staging files fails and displays hints' '
+ echo "initial" >file &&
+ git add file &&
+ git commit -m initial &&
+ echo "changes" >>file &&
+ test_must_fail git commit -m update >actual &&
+ test_i18ngrep "no changes added to commit (use \"git add\" and/or \"git commit -a\")" actual
+'
+
test_done
diff --git a/transport.c b/transport.c
index 83379a037d..1fdc7dac1a 100644
--- a/transport.c
+++ b/transport.c
@@ -737,7 +737,7 @@ static int disconnect_git(struct transport *transport)
{
struct git_transport_data *data = transport->data;
if (data->conn) {
- if (data->got_remote_heads)
+ if (data->got_remote_heads && !transport->stateless_rpc)
packet_flush(data->fd[1]);
close(data->fd[0]);
close(data->fd[1]);
diff --git a/unpack-trees.c b/unpack-trees.c
index 2399b6818b..d5f4d997da 100644
--- a/unpack-trees.c
+++ b/unpack-trees.c
@@ -372,15 +372,20 @@ static int check_updates(struct unpack_trees_options *o)
state.refresh_cache = 1;
state.istate = index;
+ if (!o->update || o->dry_run) {
+ remove_marked_cache_entries(index, 0);
+ trace_performance_leave("check_updates");
+ return 0;
+ }
+
if (o->clone)
setup_collided_checkout_detection(&state, index);
progress = get_progress(o);
- if (o->update)
- git_attr_set_direction(GIT_ATTR_CHECKOUT);
+ git_attr_set_direction(GIT_ATTR_CHECKOUT);
- if (should_update_submodules() && o->update && !o->dry_run)
+ if (should_update_submodules())
load_gitmodules_file(index, NULL);
for (i = 0; i < index->cache_nr; i++) {
@@ -388,18 +393,18 @@ static int check_updates(struct unpack_trees_options *o)
if (ce->ce_flags & CE_WT_REMOVE) {
display_progress(progress, ++cnt);
- if (o->update && !o->dry_run)
- unlink_entry(ce);
+ unlink_entry(ce);
}
}
+
remove_marked_cache_entries(index, 0);
remove_scheduled_dirs();
- if (should_update_submodules() && o->update && !o->dry_run)
+ if (should_update_submodules())
load_gitmodules_file(index, &state);
enable_delayed_checkout(&state);
- if (has_promisor_remote() && o->update && !o->dry_run) {
+ if (has_promisor_remote()) {
/*
* Prefetch the objects that are to be checked out in the loop
* below.
@@ -431,15 +436,12 @@ static int check_updates(struct unpack_trees_options *o)
ce->name);
display_progress(progress, ++cnt);
ce->ce_flags &= ~CE_UPDATE;
- if (o->update && !o->dry_run) {
- errs |= checkout_entry(ce, &state, NULL, NULL);
- }
+ errs |= checkout_entry(ce, &state, NULL, NULL);
}
}
stop_progress(&progress);
errs |= finish_delayed_checkout(&state, NULL);
- if (o->update)
- git_attr_set_direction(GIT_ATTR_CHECKIN);
+ git_attr_set_direction(GIT_ATTR_CHECKIN);
if (o->clone)
report_collided_checkout(index);
@@ -694,9 +696,11 @@ static int index_pos_by_traverse_info(struct name_entry *names,
if (pos >= 0)
BUG("This is a directory and should not exist in index");
pos = -pos - 1;
- if (!starts_with(o->src_index->cache[pos]->name, name.buf) ||
+ if (pos >= o->src_index->cache_nr ||
+ !starts_with(o->src_index->cache[pos]->name, name.buf) ||
(pos > 0 && starts_with(o->src_index->cache[pos-1]->name, name.buf)))
- BUG("pos must point at the first entry in this directory");
+ BUG("pos %d doesn't point to the first entry of %s in index",
+ pos, name.buf);
strbuf_release(&name);
return pos;
}