From: "Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>
To: git@vger.kernel.org
Cc: "Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>
Subject: [PATCH 07/24] apply: support backup log with --keep-backup
Date: Sun, 9 Dec 2018 11:44:02 +0100 [thread overview]
Message-ID: <20181209104419.12639-8-pclouds@gmail.com> (raw)
In-Reply-To: <20181209104419.12639-1-pclouds@gmail.com>
Normally changes from git-apply are not worth logging because they
come from a file and can be recovered from there. This option will
mostly be used by add--interactive.pl where patches are generated
during an interactive add session and are very much worth logging.
The logging is a bit more complicated because an update is done in two
phases. The old version of all patches is removed first then the new
one added. We need to keep track of the old version in order to make a
backup.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
Documentation/git-apply.txt | 3 +++
apply.c | 38 +++++++++++++++++++++++++++++++++++--
apply.h | 1 +
t/t2080-backup-log.sh | 25 ++++++++++++++++++++++++
4 files changed, 65 insertions(+), 2 deletions(-)
diff --git a/Documentation/git-apply.txt b/Documentation/git-apply.txt
index b9aa39000f..7b0ae790db 100644
--- a/Documentation/git-apply.txt
+++ b/Documentation/git-apply.txt
@@ -250,6 +250,9 @@ When `git apply` is used as a "better GNU patch", the user can pass
the `--unsafe-paths` option to override this safety check. This option
has no effect when `--index` or `--cached` is in use.
+--keep-backup::
+ Enable index backup log when `--cached` or `--index` is used.
+
CONFIGURATION
-------------
diff --git a/apply.c b/apply.c
index 01793d6126..716c9a658f 100644
--- a/apply.c
+++ b/apply.c
@@ -21,6 +21,7 @@
#include "quote.h"
#include "rerere.h"
#include "apply.h"
+#include "backup-log.h"
static void git_apply_config(void)
{
@@ -226,6 +227,7 @@ struct patch {
char old_oid_prefix[GIT_MAX_HEXSZ + 1];
char new_oid_prefix[GIT_MAX_HEXSZ + 1];
struct patch *next;
+ struct object_id old_oid;
/* three-way fallback result */
struct object_id threeway_stage[3];
@@ -4261,6 +4263,16 @@ static void patch_stats(struct apply_state *state, struct patch *patch)
static int remove_file(struct apply_state *state, struct patch *patch, int rmdir_empty)
{
if (state->update_index && !state->ita_only) {
+ if (state->backup_log) {
+ int pos = index_name_pos(state->repo->index,
+ patch->old_name,
+ strlen(patch->old_name));
+ if (pos >= 0)
+ oidcpy(&patch->old_oid,
+ &state->repo->index->cache[pos]->oid);
+ else
+ oidclr(&patch->old_oid);
+ }
if (remove_file_from_index(state->repo->index, patch->old_name) < 0)
return error(_("unable to remove %s from index"), patch->old_name);
}
@@ -4276,7 +4288,8 @@ static int add_index_file(struct apply_state *state,
const char *path,
unsigned mode,
void *buf,
- unsigned long size)
+ unsigned long size,
+ const struct object_id *old_oid)
{
struct stat st;
struct cache_entry *ce;
@@ -4314,6 +4327,16 @@ static int add_index_file(struct apply_state *state,
"for newly created file %s"), path);
}
}
+ if (state->backup_log) {
+ struct strbuf *sb = state->repo->index->backup_log;
+
+ if (!sb) {
+ sb = xmalloc(sizeof(*sb));
+ strbuf_init(sb, 0);
+ state->repo->index->backup_log = sb;
+ }
+ bkl_append(sb, ce->name, old_oid, &ce->oid);
+ }
if (add_index_entry(state->repo->index, ce, ADD_CACHE_OK_TO_ADD) < 0) {
discard_cache_entry(ce);
return error(_("unable to add cache entry for %s"), path);
@@ -4484,7 +4507,8 @@ static int create_file(struct apply_state *state, struct patch *patch)
if (patch->conflicted_threeway)
return add_conflicted_stages_file(state, patch);
else if (state->update_index)
- return add_index_file(state, path, mode, buf, size);
+ return add_index_file(state, path, mode, buf, size,
+ &patch->old_oid);
return 0;
}
@@ -4659,6 +4683,7 @@ static int apply_patch(struct apply_state *state,
struct patch *list = NULL, **listp = &list;
int skipped_patch = 0;
int res = 0;
+ int core_backup_log = 0;
state->patch_input_file = filename;
if (read_patch_file(&buf, fd) < 0)
@@ -4721,6 +4746,13 @@ static int apply_patch(struct apply_state *state,
goto end;
}
+ if (state->backup_log &&
+ (!state->update_index ||
+ repo_config_get_bool(state->repo, "core.backupLog",
+ &core_backup_log) ||
+ !core_backup_log))
+ state->backup_log = 0;
+
if (state->check || state->apply) {
int r = check_patch_list(state, list);
if (r == -128) {
@@ -4982,6 +5014,8 @@ int apply_parse_options(int argc, const char **argv,
N_("mark new files with `git add --intent-to-add`")),
OPT_BOOL(0, "cached", &state->cached,
N_("apply a patch without touching the working tree")),
+ OPT_BOOL(0, "keep-backup", &state->backup_log,
+ N_("log index changes if the feature is enabled")),
OPT_BOOL_F(0, "unsafe-paths", &state->unsafe_paths,
N_("accept a patch that touches outside the working area"),
PARSE_OPT_NOCOMPLETE),
diff --git a/apply.h b/apply.h
index 5948348133..d4de2ebcb9 100644
--- a/apply.h
+++ b/apply.h
@@ -51,6 +51,7 @@ struct apply_state {
int check_index; /* preimage must match the indexed version */
int update_index; /* check_index && apply */
int ita_only; /* add intent-to-add entries to the index */
+ int backup_log; /* enable backup log */
/* These control cosmetic aspect of the output */
int diffstat; /* just show a diffstat, and don't actually apply */
diff --git a/t/t2080-backup-log.sh b/t/t2080-backup-log.sh
index b19e26a807..8d1c8c5935 100755
--- a/t/t2080-backup-log.sh
+++ b/t/t2080-backup-log.sh
@@ -63,4 +63,29 @@ test_expect_success 'partial commit writes backup log' '
test_cmp expected .git/index.bkl
'
+test_expect_success 'apply --cached writes backup log' '
+ rm -f .git/index.bkl &&
+ git reset --hard &&
+ test_tick &&
+ echo to-be-deleted >to-be-deleted &&
+ echo to-be-modified >to-be-modified &&
+ OLD_M=$(git hash-object to-be-modified) &&
+ git add . &&
+ git commit -m first &&
+ rm to-be-deleted &&
+ echo modified >>to-be-modified &&
+ NEW_M=$(git hash-object to-be-modified) &&
+ OLD_A=$ZERO_OID &&
+ echo to-be-added >to-be-added &&
+ NEW_A=$(git hash-object to-be-added) &&
+ git add . &&
+ git commit -m second &&
+ git diff HEAD^ HEAD >patch &&
+ git reset --hard HEAD^ &&
+ git -c core.backupLog=true apply --cached --keep-backup patch &&
+ echo "$OLD_A $NEW_A $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $test_tick -0700 to-be-added" >expected &&
+ echo "$OLD_M $NEW_M $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $test_tick -0700 to-be-modified" >>expected &&
+ test_cmp expected .git/index.bkl
+'
+
test_done
--
2.20.0.rc2.486.g9832c05c3d
next prev parent reply other threads:[~2018-12-09 10:45 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-12-09 10:43 [RFC PATCH 00/24] Add backup log Nguyễn Thái Ngọc Duy
2018-12-09 10:43 ` [PATCH 01/24] doc: introduce new "backup log" concept Nguyễn Thái Ngọc Duy
2018-12-09 10:43 ` [PATCH 02/24] backup-log: add "update" subcommand Nguyễn Thái Ngọc Duy
2018-12-09 10:43 ` [PATCH 03/24] read-cache.c: new flag for add_index_entry() to write to backup log Nguyễn Thái Ngọc Duy
2018-12-09 10:43 ` [PATCH 04/24] add: support " Nguyễn Thái Ngọc Duy
2018-12-09 10:44 ` [PATCH 05/24] update-index: support backup log with --keep-backup Nguyễn Thái Ngọc Duy
2018-12-09 10:44 ` [PATCH 06/24] commit: support backup log Nguyễn Thái Ngọc Duy
2018-12-09 10:44 ` Nguyễn Thái Ngọc Duy [this message]
2018-12-09 10:44 ` [PATCH 08/24] add--interactive: " Nguyễn Thái Ngọc Duy
2018-12-09 10:44 ` [PATCH 09/24] backup-log.c: add API for walking " Nguyễn Thái Ngọc Duy
2018-12-09 10:44 ` [PATCH 10/24] backup-log: add cat command Nguyễn Thái Ngọc Duy
2018-12-09 10:44 ` [PATCH 11/24] backup-log: add diff command Nguyễn Thái Ngọc Duy
2018-12-09 10:44 ` [PATCH 12/24] backup-log: add log command Nguyễn Thái Ngọc Duy
2018-12-09 10:44 ` [PATCH 13/24] backup-log: add prune command Nguyễn Thái Ngọc Duy
2018-12-09 10:44 ` [PATCH 14/24] gc: prune backup logs Nguyễn Thái Ngọc Duy
2018-12-09 10:44 ` [PATCH 15/24] backup-log: keep all blob references around Nguyễn Thái Ngọc Duy
2018-12-09 10:44 ` [PATCH 16/24] sha1-file.c: let index_path() accept NULL istate Nguyễn Thái Ngọc Duy
2018-12-09 10:44 ` [PATCH 17/24] config --edit: support backup log Nguyễn Thái Ngọc Duy
2018-12-09 10:44 ` [PATCH 18/24] refs: keep backup of deleted reflog Nguyễn Thái Ngọc Duy
2018-12-09 10:44 ` [PATCH 19/24] unpack-trees.c: keep backup of ignored files being overwritten Nguyễn Thái Ngọc Duy
2018-12-09 10:44 ` [PATCH 20/24] reset --hard: keep backup of overwritten files Nguyễn Thái Ngọc Duy
2018-12-09 10:44 ` [PATCH 21/24] checkout -f: " Nguyễn Thái Ngọc Duy
2018-12-09 10:44 ` [PATCH 22/24] am: keep backup of overwritten files on --skip or --abort Nguyễn Thái Ngọc Duy
2018-12-09 10:44 ` [PATCH 23/24] rebase: " Nguyễn Thái Ngọc Duy
2018-12-09 10:44 ` [PATCH 24/24] FIXME Nguyễn Thái Ngọc Duy
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=20181209104419.12639-8-pclouds@gmail.com \
--to=pclouds@gmail.com \
--cc=git@vger.kernel.org \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).