From: Denton Liu <liu.denton@gmail.com>
To: Git Mailing List <git@vger.kernel.org>
Cc: Junio C Hamano <gitster@pobox.com>,
Eric Sunshine <sunshine@sunshineco.com>
Subject: [PATCH v3 0/2] stash show: learn --include-untracked and --only-untracked
Date: Mon, 15 Feb 2021 23:11:55 -0800 [thread overview]
Message-ID: <cover.1613459474.git.liu.denton@gmail.com> (raw)
In-Reply-To: <cover.1612855690.git.liu.denton@gmail.com>
A blindspot that I've noticed in git is that it's not possible to
properly view a stash entry that has untracked files via `git stash
show`. Teach `git stash show --include-untracked` which should do this.
In addition, this series also teaches `--only-untracked` and the
`stash.showIncludeUntracked` config option.
This series is based on 'dl/stash-cleanup'.
Changes since v2:
* Base this series on top of 'dl/stash-cleanup'
* Attempt to replicate the read-tree code to merge the untracked tree
Changes since v1:
* Add a dash for <log-options> and <diff-options>
* Fix the misspelling of --include-untracked in a commit message
* Change the approach from concatenating diffs to using `git read-tree`
Denton Liu (2):
stash show: teach --include-untracked and --only-untracked
stash show: learn stash.showIncludeUntracked
Documentation/config/stash.txt | 5 ++
Documentation/git-stash.txt | 22 ++++---
builtin/stash.c | 61 +++++++++++++++++-
contrib/completion/git-completion.bash | 2 +-
t/t3905-stash-include-untracked.sh | 86 ++++++++++++++++++++++++++
5 files changed, 167 insertions(+), 9 deletions(-)
Range-diff against v2:
1: 88d4791259 ! 1: 85b81f2f06 stash show: teach --include-untracked and --only-untracked
@@ Commit message
stash entry itself, running `git stash show` does not include the
untracked files as part of the diff.
- Teach stash the --include-untracked option, which also displays the
- untracked files in a stash entry from the third parent (if it exists).
- Do this via something like
+ With --include-untracked, untracked paths, which are recorded in the
+ third-parent if it exists, are shown in addition to the paths that have
+ modifications between the stash base and the working tree in the stash.
- GIT_INDEX_FILE=... git read-tree stash stash^3
-
- and diffing the resulting tree object against the stash base.
-
- One improvement that this could use for the future is performing the
- action without writing anything to disk as one would expect this to be a
- read-only operation. This can be fixed in the future, however.
-
- Another limitation of this is that it would be possible to manually
- craft a stash entry where duplicate untracked files in the stash entry
- will mask tracked files. This seems like an instance of "Doctor, it
- hurts when I do this! So don't do that!" so this can be written off.
+ One limitation of this is that it would be possible to manually craft a
+ stash entry where duplicate untracked files in the stash entry will mask
+ tracked files. This seems like an instance of "Doctor, it hurts when I
+ do this! So don't do that!" so this can be written off.
Also, teach stash the --only-untracked option which only shows the
untracked files of a stash entry. This is similar to `git show stash^3`
but it is nice to provide a convenient abstraction for it so that users
do not have to think about the underlying implementation.
+
+ ## Notes ##
+ I am not familiar with the read-tree code so this attempt at replicating
+ the read-tree code may in diff_include_untracked() may be incorrect
+ (particularly the use of the_index?).
+
+ Also, I could not figure out how to make unpack_trees() error out in the
+ case where untracked tree entry contains duplicate entries with the
+ worktree entry.
+
## Documentation/git-stash.txt ##
+@@ Documentation/git-stash.txt: SYNOPSIS
+ --------
+ [verse]
+ 'git stash' list [<log-options>]
+-'git stash' show [<diff-options>] [<stash>]
++'git stash' show [-u|--include-untracked|--only-untracked] [<diff-options>] [<stash>]
+ 'git stash' drop [-q|--quiet] [<stash>]
+ 'git stash' ( pop | apply ) [--index] [-q|--quiet] [<stash>]
+ 'git stash' branch <branchname> [<stash>]
@@ Documentation/git-stash.txt: stash@{1}: On master: 9cc0589... Add git-stash
The command takes options applicable to the 'git log'
command to control what is shown and how. See linkgit:git-log[1].
@@ builtin/stash.c: static int git_stash_config(const char *var, const char *value,
return git_diff_basic_config(var, value, cb);
}
-+static int merge_track_untracked(struct object_id *result, const struct stash_info *info)
++static void diff_include_untracked(const struct stash_info *info, struct diff_options *diff_opt)
+{
-+ int ret = 0;
-+ struct index_state istate = { NULL };
-+ struct child_process cp_read_tree = CHILD_PROCESS_INIT;
++ const struct object_id *oid[] = { &info->w_commit, &info->u_tree };
++ struct tree *tree[ARRAY_SIZE(oid)];
++ struct tree_desc tree_desc[ARRAY_SIZE(oid)];
++ struct unpack_trees_options unpack_tree_opt = { 0 };
++ int i;
+
-+ if (!info->has_u) {
-+ oidcpy(result, &info->w_commit);
-+ return 0;
++ for (i = 0; i < ARRAY_SIZE(oid); i++) {
++ tree[i] = parse_tree_indirect(oid[i]);
++ if (parse_tree(tree[i]) < 0)
++ die(_("failed to parse tree"));
++ init_tree_desc(&tree_desc[i], tree[i]->buffer, tree[i]->size);
+ }
+
-+ /*
-+ * TODO: is there a way of doing this all in-memory without writing
-+ * anything to disk?
-+ */
-+ remove_path(stash_index_path.buf);
++ unpack_tree_opt.head_idx = -1;
++ unpack_tree_opt.src_index = &the_index;
++ unpack_tree_opt.dst_index = &the_index;
++ unpack_tree_opt.fn = twoway_merge;
+
-+ cp_read_tree.git_cmd = 1;
-+ strvec_push(&cp_read_tree.args, "read-tree");
-+ strvec_push(&cp_read_tree.args, oid_to_hex(&info->w_commit));
-+ strvec_push(&cp_read_tree.args, oid_to_hex(&info->u_tree));
-+ strvec_pushf(&cp_read_tree.env_array, "GIT_INDEX_FILE=%s",
-+ stash_index_path.buf);
++ if (unpack_trees(ARRAY_SIZE(tree_desc), tree_desc, &unpack_tree_opt))
++ die(_("failed to unpack trees"));
+
-+ if (run_command(&cp_read_tree)) {
-+ ret = -1;
-+ goto done;
-+ }
-+
-+ if (write_index_as_tree(result, &istate, stash_index_path.buf, 0,
-+ NULL)) {
-+ ret = -1;
-+ goto done;
-+ }
-+
-+done:
-+ discard_index(&istate);
-+ remove_path(stash_index_path.buf);
-+ return ret;
++ do_diff_cache(&info->b_commit, diff_opt);
+}
+
static int show_stash(int argc, const char **argv, const char *prefix)
@@ builtin/stash.c: static int show_stash(int argc, const char **argv, const char *
struct rev_info rev;
struct strvec stash_args = STRVEC_INIT;
struct strvec revision_args = STRVEC_INIT;
-+ struct object_id *before = NULL;
-+ struct object_id *after = NULL;
-+ struct object_id untracked_merged_tree;
+ enum {
+ UNTRACKED_NONE,
+ UNTRACKED_INCLUDE,
@@ builtin/stash.c: static int show_stash(int argc, const char **argv, const char *
- diff_tree_oid(&info.b_commit, &info.w_commit, "", &rev.diffopt);
+ switch (show_untracked) {
+ case UNTRACKED_NONE:
-+ before = &info.b_commit;
-+ after = &info.w_commit;
++ diff_tree_oid(&info.b_commit, &info.w_commit, "", &rev.diffopt);
+ break;
+ case UNTRACKED_ONLY:
-+ before = NULL;
-+ after = &info.u_tree;
++ diff_root_tree_oid(&info.u_tree, "", &rev.diffopt);
+ break;
+ case UNTRACKED_INCLUDE:
-+ if (merge_track_untracked(&untracked_merged_tree, &info) < 0)
-+ die(_("unable merge stash index with untracked files index"));
-+ before = &info.b_commit;
-+ after = &untracked_merged_tree;
++ diff_include_untracked(&info, &rev.diffopt);
+ break;
+ }
-+ diff_tree_oid(before, after, "", &rev.diffopt);
log_tree_diff_flush(&rev);
free_stash_info(&info);
2: ac4019f47e = 2: d19d07ec27 stash show: learn stash.showIncludeUntracked
--
2.30.0.478.g8a0d178c01
next prev parent reply other threads:[~2021-02-16 7:13 UTC|newest]
Thread overview: 46+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-02-02 9:31 [PATCH 0/9] stash show: learn --include-untracked and --only-untracked Denton Liu
2021-02-02 9:33 ` Denton Liu
2021-02-02 9:33 ` [PATCH 1/9] git-stash.txt: be explicit about subcommand options Denton Liu
2021-02-02 17:37 ` Eric Sunshine
2021-02-02 9:33 ` [PATCH 2/9] t3905: remove spaces after redirect operators Denton Liu
2021-02-02 9:33 ` [PATCH 3/9] t3905: move all commands into test cases Denton Liu
2021-02-02 21:41 ` Junio C Hamano
2021-02-02 9:33 ` [PATCH 4/9] t3905: remove nested git in command substitution Denton Liu
2021-02-02 9:33 ` [PATCH 5/9] t3905: replace test -s with test_file_not_empty Denton Liu
2021-02-02 9:33 ` [PATCH 6/9] t3905: use test_cmp() to check file contents Denton Liu
2021-02-02 9:33 ` [PATCH 7/9] stash: declare ref_stash as an array Denton Liu
2021-02-02 21:46 ` Junio C Hamano
2021-02-02 9:33 ` [PATCH 8/9] stash show: teach --include-tracked and --only-untracked Denton Liu
2021-02-02 21:56 ` Junio C Hamano
2021-02-02 9:33 ` [PATCH 9/9] stash show: learn stash.showIncludeUntracked Denton Liu
2021-02-09 7:28 ` [PATCH v2 0/9] stash show: learn --include-untracked and --only-untracked Denton Liu
2021-02-09 7:28 ` [PATCH v2 1/9] git-stash.txt: be explicit about subcommand options Denton Liu
2021-02-10 7:17 ` Junio C Hamano
2021-02-11 19:07 ` [PATCH] fixup! " Denton Liu
2021-02-09 7:28 ` [PATCH v2 2/9] t3905: remove spaces after redirect operators Denton Liu
2021-02-10 7:18 ` Junio C Hamano
2021-02-09 7:28 ` [PATCH v2 3/9] t3905: move all commands into test cases Denton Liu
2021-02-09 7:28 ` [PATCH v2 4/9] t3905: remove nested git in command substitution Denton Liu
2021-02-10 7:24 ` Junio C Hamano
2021-02-09 7:28 ` [PATCH v2 5/9] t3905: replace test -s with test_file_not_empty Denton Liu
2021-02-09 7:28 ` [PATCH v2 6/9] t3905: use test_cmp() to check file contents Denton Liu
2021-02-09 7:28 ` [PATCH v2 7/9] stash: declare ref_stash as an array Denton Liu
2021-02-10 7:28 ` Junio C Hamano
2021-02-09 7:28 ` [PATCH v2 8/9] stash show: teach --include-untracked and --only-untracked Denton Liu
2021-02-10 7:53 ` Junio C Hamano
2021-02-16 3:15 ` Denton Liu
2021-02-16 6:42 ` Junio C Hamano
2021-02-09 7:28 ` [PATCH v2 9/9] stash show: learn stash.showIncludeUntracked Denton Liu
2021-02-16 7:11 ` Denton Liu [this message]
2021-02-16 7:11 ` [PATCH v3 1/2] stash show: teach --include-untracked and --only-untracked Denton Liu
2021-02-16 20:22 ` Junio C Hamano
2021-02-17 11:18 ` Denton Liu
2021-02-17 17:50 ` Junio C Hamano
2021-02-17 2:31 ` Junio C Hamano
2021-02-16 7:11 ` [PATCH v3 2/2] stash show: learn stash.showIncludeUntracked Denton Liu
2021-03-03 11:16 ` [PATCH v4 0/2] stash show: learn --include-untracked and --only-untracked Denton Liu
2021-03-03 11:16 ` [PATCH v4 1/2] stash show: teach " Denton Liu
2021-03-03 11:16 ` [PATCH v4 2/2] stash show: learn stash.showIncludeUntracked Denton Liu
2021-03-04 0:38 ` [PATCH v4 0/2] stash show: learn --include-untracked and --only-untracked Junio C Hamano
2021-03-04 1:33 ` Denton Liu
2021-03-04 1:42 ` Denton Liu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=cover.1613459474.git.liu.denton@gmail.com \
--to=liu.denton@gmail.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=sunshine@sunshineco.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.