Merge branch 'jc/fsck-reflog'
* jc/fsck-reflog: Add git-reflog to .gitignore reflog expire: do not punt on tags that point at non commits. reflog expire: prune commits that are not incomplete Don't crash during repack of a reflog with pruned commits. git reflog expire Move in_merge_bases() to commit.c reflog: fix warning message. Teach git-repack to preserve objects referred to by reflog entries. Protect commits recorded in reflog from pruning. add for_each_reflog_ent() iterator
This commit is contained in:
commit
e8b4029f99
1
.gitignore
vendored
1
.gitignore
vendored
@ -89,6 +89,7 @@ git-quiltimport
|
||||
git-read-tree
|
||||
git-rebase
|
||||
git-receive-pack
|
||||
git-reflog
|
||||
git-relink
|
||||
git-repack
|
||||
git-repo-config
|
||||
|
1
Makefile
1
Makefile
@ -287,6 +287,7 @@ BUILTIN_OBJS = \
|
||||
builtin-prune-packed.o \
|
||||
builtin-push.o \
|
||||
builtin-read-tree.o \
|
||||
builtin-reflog.o \
|
||||
builtin-repo-config.o \
|
||||
builtin-rerere.o \
|
||||
builtin-rev-list.o \
|
||||
|
@ -74,25 +74,6 @@ const char *branch_get_color(enum color_branch ix)
|
||||
return "";
|
||||
}
|
||||
|
||||
static int in_merge_bases(const unsigned char *sha1,
|
||||
struct commit *rev1,
|
||||
struct commit *rev2)
|
||||
{
|
||||
struct commit_list *bases, *b;
|
||||
int ret = 0;
|
||||
|
||||
bases = get_merge_bases(rev1, rev2, 1);
|
||||
for (b = bases; b; b = b->next) {
|
||||
if (!hashcmp(sha1, b->item->object.sha1)) {
|
||||
ret = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
free_commit_list(bases);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int delete_branches(int argc, const char **argv, int force, int kinds)
|
||||
{
|
||||
struct commit *rev, *head_rev = head_rev;
|
||||
@ -153,7 +134,7 @@ static int delete_branches(int argc, const char **argv, int force, int kinds)
|
||||
*/
|
||||
|
||||
if (!force &&
|
||||
!in_merge_bases(sha1, rev, head_rev)) {
|
||||
!in_merge_bases(rev, head_rev)) {
|
||||
error("The branch '%s' is not a strict subset of "
|
||||
"your current HEAD.\n"
|
||||
"If you are sure you want to delete it, "
|
||||
|
@ -17,7 +17,7 @@ static const char pack_usage[] = "\
|
||||
git-pack-objects [{ -q | --progress | --all-progress }] \n\
|
||||
[--local] [--incremental] [--window=N] [--depth=N] \n\
|
||||
[--no-reuse-delta] [--delta-base-offset] [--non-empty] \n\
|
||||
[--revs [--unpacked | --all]*] [--stdout | base-name] \n\
|
||||
[--revs [--unpacked | --all]*] [--reflog] [--stdout | base-name] \n\
|
||||
[<ref-list | <object-list]";
|
||||
|
||||
struct object_entry {
|
||||
@ -1575,6 +1575,7 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
|
||||
}
|
||||
if (!strcmp("--unpacked", arg) ||
|
||||
!strncmp("--unpacked=", arg, 11) ||
|
||||
!strcmp("--reflog", arg) ||
|
||||
!strcmp("--all", arg)) {
|
||||
use_internal_rev_list = 1;
|
||||
if (ARRAY_SIZE(rp_av) - 1 <= rp_ac)
|
||||
|
@ -181,12 +181,28 @@ static void walk_commit_list(struct rev_info *revs)
|
||||
}
|
||||
}
|
||||
|
||||
static int add_one_reflog_ent(unsigned char *osha1, unsigned char *nsha1, char *datail, void *cb_data)
|
||||
{
|
||||
struct object *object;
|
||||
|
||||
object = parse_object(osha1);
|
||||
if (object)
|
||||
add_pending_object(&revs, object, "");
|
||||
object = parse_object(nsha1);
|
||||
if (object)
|
||||
add_pending_object(&revs, object, "");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int add_one_ref(const char *path, const unsigned char *sha1, int flag, void *cb_data)
|
||||
{
|
||||
struct object *object = parse_object(sha1);
|
||||
if (!object)
|
||||
die("bad object ref: %s:%s", path, sha1_to_hex(sha1));
|
||||
add_pending_object(&revs, object, "");
|
||||
|
||||
for_each_reflog_ent(path, add_one_reflog_ent, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
212
builtin-reflog.c
Normal file
212
builtin-reflog.c
Normal file
@ -0,0 +1,212 @@
|
||||
#include "cache.h"
|
||||
#include "builtin.h"
|
||||
#include "commit.h"
|
||||
#include "refs.h"
|
||||
#include "dir.h"
|
||||
#include "tree-walk.h"
|
||||
|
||||
struct expire_reflog_cb {
|
||||
FILE *newlog;
|
||||
const char *ref;
|
||||
struct commit *ref_commit;
|
||||
unsigned long expire_total;
|
||||
unsigned long expire_unreachable;
|
||||
};
|
||||
|
||||
static int tree_is_complete(const unsigned char *sha1)
|
||||
{
|
||||
struct tree_desc desc;
|
||||
void *buf;
|
||||
char type[20];
|
||||
|
||||
buf = read_sha1_file(sha1, type, &desc.size);
|
||||
if (!buf)
|
||||
return 0;
|
||||
desc.buf = buf;
|
||||
while (desc.size) {
|
||||
const unsigned char *elem;
|
||||
const char *name;
|
||||
unsigned mode;
|
||||
|
||||
elem = tree_entry_extract(&desc, &name, &mode);
|
||||
if (!has_sha1_file(elem) ||
|
||||
(S_ISDIR(mode) && !tree_is_complete(elem))) {
|
||||
free(buf);
|
||||
return 0;
|
||||
}
|
||||
update_tree_entry(&desc);
|
||||
}
|
||||
free(buf);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int keep_entry(struct commit **it, unsigned char *sha1)
|
||||
{
|
||||
struct commit *commit;
|
||||
|
||||
*it = NULL;
|
||||
if (is_null_sha1(sha1))
|
||||
return 1;
|
||||
commit = lookup_commit_reference_gently(sha1, 1);
|
||||
if (!commit)
|
||||
return 0;
|
||||
|
||||
/* Make sure everything in this commit exists. */
|
||||
parse_object(commit->object.sha1);
|
||||
if (!tree_is_complete(commit->tree->object.sha1))
|
||||
return 0;
|
||||
*it = commit;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int expire_reflog_ent(unsigned char *osha1, unsigned char *nsha1,
|
||||
char *data, void *cb_data)
|
||||
{
|
||||
struct expire_reflog_cb *cb = cb_data;
|
||||
unsigned long timestamp;
|
||||
char *cp, *ep;
|
||||
struct commit *old, *new;
|
||||
|
||||
cp = strchr(data, '>');
|
||||
if (!cp || *++cp != ' ')
|
||||
goto prune;
|
||||
timestamp = strtoul(cp, &ep, 10);
|
||||
if (*ep != ' ')
|
||||
goto prune;
|
||||
if (timestamp < cb->expire_total)
|
||||
goto prune;
|
||||
|
||||
if (!keep_entry(&old, osha1) || !keep_entry(&new, nsha1))
|
||||
goto prune;
|
||||
|
||||
if ((timestamp < cb->expire_unreachable) &&
|
||||
(!cb->ref_commit ||
|
||||
(old && !in_merge_bases(old, cb->ref_commit)) ||
|
||||
(new && !in_merge_bases(new, cb->ref_commit))))
|
||||
goto prune;
|
||||
|
||||
if (cb->newlog)
|
||||
fprintf(cb->newlog, "%s %s %s",
|
||||
sha1_to_hex(osha1), sha1_to_hex(nsha1), data);
|
||||
return 0;
|
||||
prune:
|
||||
if (!cb->newlog)
|
||||
fprintf(stderr, "would prune %s", data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct cmd_reflog_expire_cb {
|
||||
int dry_run;
|
||||
unsigned long expire_total;
|
||||
unsigned long expire_unreachable;
|
||||
};
|
||||
|
||||
static int expire_reflog(const char *ref, const unsigned char *sha1, int unused, void *cb_data)
|
||||
{
|
||||
struct cmd_reflog_expire_cb *cmd = cb_data;
|
||||
struct expire_reflog_cb cb;
|
||||
struct ref_lock *lock;
|
||||
char *newlog_path = NULL;
|
||||
int status = 0;
|
||||
|
||||
if (strncmp(ref, "refs/", 5))
|
||||
return error("not a ref '%s'", ref);
|
||||
|
||||
memset(&cb, 0, sizeof(cb));
|
||||
/* we take the lock for the ref itself to prevent it from
|
||||
* getting updated.
|
||||
*/
|
||||
lock = lock_ref_sha1(ref + 5, sha1);
|
||||
if (!lock)
|
||||
return error("cannot lock ref '%s'", ref);
|
||||
if (!file_exists(lock->log_file))
|
||||
goto finish;
|
||||
if (!cmd->dry_run) {
|
||||
newlog_path = xstrdup(git_path("logs/%s.lock", ref));
|
||||
cb.newlog = fopen(newlog_path, "w");
|
||||
}
|
||||
|
||||
cb.ref_commit = lookup_commit_reference_gently(sha1, 1);
|
||||
if (!cb.ref_commit)
|
||||
fprintf(stderr,
|
||||
"warning: ref '%s' does not point at a commit\n", ref);
|
||||
cb.ref = ref;
|
||||
cb.expire_total = cmd->expire_total;
|
||||
cb.expire_unreachable = cmd->expire_unreachable;
|
||||
for_each_reflog_ent(ref, expire_reflog_ent, &cb);
|
||||
finish:
|
||||
if (cb.newlog) {
|
||||
if (fclose(cb.newlog))
|
||||
status |= error("%s: %s", strerror(errno),
|
||||
newlog_path);
|
||||
if (rename(newlog_path, lock->log_file)) {
|
||||
status |= error("cannot rename %s to %s",
|
||||
newlog_path, lock->log_file);
|
||||
unlink(newlog_path);
|
||||
}
|
||||
}
|
||||
free(newlog_path);
|
||||
unlock_ref(lock);
|
||||
return status;
|
||||
}
|
||||
|
||||
static const char reflog_expire_usage[] =
|
||||
"git-reflog expire [--dry-run] [--expire=<time>] [--expire-unreachable=<time>] [--all] <refs>...";
|
||||
|
||||
static int cmd_reflog_expire(int argc, const char **argv, const char *prefix)
|
||||
{
|
||||
struct cmd_reflog_expire_cb cb;
|
||||
unsigned long now = time(NULL);
|
||||
int i, status, do_all;
|
||||
|
||||
save_commit_buffer = 0;
|
||||
do_all = status = 0;
|
||||
memset(&cb, 0, sizeof(cb));
|
||||
cb.expire_total = now - 90 * 24 * 3600;
|
||||
cb.expire_unreachable = now - 30 * 24 * 3600;
|
||||
|
||||
for (i = 1; i < argc; i++) {
|
||||
const char *arg = argv[i];
|
||||
if (!strcmp(arg, "--dry-run") || !strcmp(arg, "-n"))
|
||||
cb.dry_run = 1;
|
||||
else if (!strncmp(arg, "--expire=", 9))
|
||||
cb.expire_total = approxidate(arg + 9);
|
||||
else if (!strncmp(arg, "--expire-unreachable=", 21))
|
||||
cb.expire_unreachable = approxidate(arg + 21);
|
||||
else if (!strcmp(arg, "--all"))
|
||||
do_all = 1;
|
||||
else if (!strcmp(arg, "--")) {
|
||||
i++;
|
||||
break;
|
||||
}
|
||||
else if (arg[0] == '-')
|
||||
usage(reflog_expire_usage);
|
||||
else
|
||||
break;
|
||||
}
|
||||
if (do_all)
|
||||
status |= for_each_ref(expire_reflog, &cb);
|
||||
while (i < argc) {
|
||||
const char *ref = argv[i++];
|
||||
unsigned char sha1[20];
|
||||
if (!resolve_ref(ref, sha1, 1, NULL)) {
|
||||
status |= error("%s points nowhere!", ref);
|
||||
continue;
|
||||
}
|
||||
status |= expire_reflog(ref, sha1, 0, &cb);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
static const char reflog_usage[] =
|
||||
"git-reflog (expire | ...)";
|
||||
|
||||
int cmd_reflog(int argc, const char **argv, const char *prefix)
|
||||
{
|
||||
if (argc < 2)
|
||||
usage(reflog_usage);
|
||||
else if (!strcmp(argv[1], "expire"))
|
||||
return cmd_reflog_expire(argc - 1, argv + 1, prefix);
|
||||
else
|
||||
usage(reflog_usage);
|
||||
}
|
@ -51,6 +51,7 @@ extern int cmd_prune(int argc, const char **argv, const char *prefix);
|
||||
extern int cmd_prune_packed(int argc, const char **argv, const char *prefix);
|
||||
extern int cmd_push(int argc, const char **argv, const char *prefix);
|
||||
extern int cmd_read_tree(int argc, const char **argv, const char *prefix);
|
||||
extern int cmd_reflog(int argc, const char **argv, const char *prefix);
|
||||
extern int cmd_repo_config(int argc, const char **argv, const char *prefix);
|
||||
extern int cmd_rerere(int argc, const char **argv, const char *prefix);
|
||||
extern int cmd_rev_list(int argc, const char **argv, const char *prefix);
|
||||
|
17
commit.c
17
commit.c
@ -1009,3 +1009,20 @@ struct commit_list *get_merge_bases(struct commit *one,
|
||||
free(rslt);
|
||||
return result;
|
||||
}
|
||||
|
||||
int in_merge_bases(struct commit *rev1, struct commit *rev2)
|
||||
{
|
||||
struct commit_list *bases, *b;
|
||||
int ret = 0;
|
||||
|
||||
bases = get_merge_bases(rev1, rev2, 1);
|
||||
for (b = bases; b; b = b->next) {
|
||||
if (!hashcmp(rev1->object.sha1, b->item->object.sha1)) {
|
||||
ret = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
free_commit_list(bases);
|
||||
return ret;
|
||||
}
|
||||
|
1
commit.h
1
commit.h
@ -107,4 +107,5 @@ int read_graft_file(const char *graft_file);
|
||||
|
||||
extern struct commit_list *get_merge_bases(struct commit *rev1, struct commit *rev2, int cleanup);
|
||||
|
||||
int in_merge_bases(struct commit *rev1, struct commit *rev2);
|
||||
#endif /* COMMIT_H */
|
||||
|
@ -399,6 +399,25 @@ static void fsck_dir(int i, char *path)
|
||||
|
||||
static int default_refs;
|
||||
|
||||
static int fsck_handle_reflog_ent(unsigned char *osha1, unsigned char *nsha1, char *datail, void *cb_data)
|
||||
{
|
||||
struct object *obj;
|
||||
|
||||
if (!is_null_sha1(osha1)) {
|
||||
obj = lookup_object(osha1);
|
||||
if (obj) {
|
||||
obj->used = 1;
|
||||
mark_reachable(obj, REACHABLE);
|
||||
}
|
||||
}
|
||||
obj = lookup_object(nsha1);
|
||||
if (obj) {
|
||||
obj->used = 1;
|
||||
mark_reachable(obj, REACHABLE);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fsck_handle_ref(const char *refname, const unsigned char *sha1, int flag, void *cb_data)
|
||||
{
|
||||
struct object *obj;
|
||||
@ -416,6 +435,9 @@ static int fsck_handle_ref(const char *refname, const unsigned char *sha1, int f
|
||||
default_refs++;
|
||||
obj->used = 1;
|
||||
mark_reachable(obj, REACHABLE);
|
||||
|
||||
for_each_reflog_ent(refname, fsck_handle_reflog_ent, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -62,7 +62,7 @@ case ",$all_into_one," in
|
||||
esac
|
||||
|
||||
args="$args $local $quiet $no_reuse_delta$extra"
|
||||
name=$(git-pack-objects --non-empty --all $args </dev/null "$PACKTMP") ||
|
||||
name=$(git-pack-objects --non-empty --all --reflog $args </dev/null "$PACKTMP") ||
|
||||
exit 1
|
||||
if [ -z "$name" ]; then
|
||||
echo Nothing new to pack.
|
||||
|
1
git.c
1
git.c
@ -246,6 +246,7 @@ static void handle_internal_command(int argc, const char **argv, char **envp)
|
||||
{ "prune-packed", cmd_prune_packed, RUN_SETUP },
|
||||
{ "push", cmd_push, RUN_SETUP },
|
||||
{ "read-tree", cmd_read_tree, RUN_SETUP },
|
||||
{ "reflog", cmd_reflog, RUN_SETUP },
|
||||
{ "repo-config", cmd_repo_config },
|
||||
{ "rerere", cmd_rerere, RUN_SETUP },
|
||||
{ "rev-list", cmd_rev_list, RUN_SETUP },
|
||||
|
37
refs.c
37
refs.c
@ -1013,7 +1013,7 @@ int read_ref_at(const char *ref, unsigned long at_time, int cnt, unsigned char *
|
||||
{
|
||||
const char *logfile, *logdata, *logend, *rec, *lastgt, *lastrec;
|
||||
char *tz_c;
|
||||
int logfd, tz;
|
||||
int logfd, tz, reccnt = 0;
|
||||
struct stat st;
|
||||
unsigned long date;
|
||||
unsigned char logged_sha1[20];
|
||||
@ -1031,6 +1031,7 @@ int read_ref_at(const char *ref, unsigned long at_time, int cnt, unsigned char *
|
||||
lastrec = NULL;
|
||||
rec = logend = logdata + st.st_size;
|
||||
while (logdata < rec) {
|
||||
reccnt++;
|
||||
if (logdata < rec && *(rec-1) == '\n')
|
||||
rec--;
|
||||
lastgt = NULL;
|
||||
@ -1087,7 +1088,37 @@ int read_ref_at(const char *ref, unsigned long at_time, int cnt, unsigned char *
|
||||
if (get_sha1_hex(logdata, sha1))
|
||||
die("Log %s is corrupt.", logfile);
|
||||
munmap((void*)logdata, st.st_size);
|
||||
fprintf(stderr, "warning: Log %s only goes back to %s.\n",
|
||||
logfile, show_rfc2822_date(date, tz));
|
||||
if (at_time)
|
||||
fprintf(stderr, "warning: Log %s only goes back to %s.\n",
|
||||
logfile, show_rfc2822_date(date, tz));
|
||||
else
|
||||
fprintf(stderr, "warning: Log %s only has %d entries.\n",
|
||||
logfile, reccnt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void for_each_reflog_ent(const char *ref, each_reflog_ent_fn fn, void *cb_data)
|
||||
{
|
||||
const char *logfile;
|
||||
FILE *logfp;
|
||||
char buf[1024];
|
||||
|
||||
logfile = git_path("logs/%s", ref);
|
||||
logfp = fopen(logfile, "r");
|
||||
if (!logfp)
|
||||
return;
|
||||
while (fgets(buf, sizeof(buf), logfp)) {
|
||||
unsigned char osha1[20], nsha1[20];
|
||||
int len;
|
||||
|
||||
/* old SP new SP name <email> SP time TAB msg LF */
|
||||
len = strlen(buf);
|
||||
if (len < 83 || buf[len-1] != '\n' ||
|
||||
get_sha1_hex(buf, osha1) || buf[40] != ' ' ||
|
||||
get_sha1_hex(buf + 41, nsha1) || buf[81] != ' ')
|
||||
continue; /* corrupt? */
|
||||
fn(osha1, nsha1, buf+82, cb_data);
|
||||
}
|
||||
fclose(logfp);
|
||||
}
|
||||
|
||||
|
4
refs.h
4
refs.h
@ -44,6 +44,10 @@ extern int write_ref_sha1(struct ref_lock *lock, const unsigned char *sha1, cons
|
||||
/** Reads log for the value of ref during at_time. **/
|
||||
extern int read_ref_at(const char *ref, unsigned long at_time, int cnt, unsigned char *sha1);
|
||||
|
||||
/* iterate over reflog entries */
|
||||
typedef int each_reflog_ent_fn(unsigned char *osha1, unsigned char *nsha1, char *, void *);
|
||||
void for_each_reflog_ent(const char *ref, each_reflog_ent_fn fn, void *cb_data);
|
||||
|
||||
/** Returns 0 if target has the right format for a ref. **/
|
||||
extern int check_ref_format(const char *target);
|
||||
|
||||
|
66
revision.c
66
revision.c
@ -464,21 +464,69 @@ static void limit_list(struct rev_info *revs)
|
||||
revs->commits = newlist;
|
||||
}
|
||||
|
||||
static int all_flags;
|
||||
static struct rev_info *all_revs;
|
||||
struct all_refs_cb {
|
||||
int all_flags;
|
||||
int warned_bad_reflog;
|
||||
struct rev_info *all_revs;
|
||||
const char *name_for_errormsg;
|
||||
};
|
||||
|
||||
static int handle_one_ref(const char *path, const unsigned char *sha1, int flag, void *cb_data)
|
||||
{
|
||||
struct object *object = get_reference(all_revs, path, sha1, all_flags);
|
||||
add_pending_object(all_revs, object, "");
|
||||
struct all_refs_cb *cb = cb_data;
|
||||
struct object *object = get_reference(cb->all_revs, path, sha1,
|
||||
cb->all_flags);
|
||||
add_pending_object(cb->all_revs, object, "");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void handle_all(struct rev_info *revs, unsigned flags)
|
||||
{
|
||||
all_revs = revs;
|
||||
all_flags = flags;
|
||||
for_each_ref(handle_one_ref, NULL);
|
||||
struct all_refs_cb cb;
|
||||
cb.all_revs = revs;
|
||||
cb.all_flags = flags;
|
||||
for_each_ref(handle_one_ref, &cb);
|
||||
}
|
||||
|
||||
static void handle_one_reflog_commit(unsigned char *sha1, void *cb_data)
|
||||
{
|
||||
struct all_refs_cb *cb = cb_data;
|
||||
if (!is_null_sha1(sha1)) {
|
||||
struct object *o = parse_object(sha1);
|
||||
if (o) {
|
||||
o->flags |= cb->all_flags;
|
||||
add_pending_object(cb->all_revs, o, "");
|
||||
}
|
||||
else if (!cb->warned_bad_reflog) {
|
||||
warn("reflog of '%s' references pruned commits",
|
||||
cb->name_for_errormsg);
|
||||
cb->warned_bad_reflog = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int handle_one_reflog_ent(unsigned char *osha1, unsigned char *nsha1, char *detail, void *cb_data)
|
||||
{
|
||||
handle_one_reflog_commit(osha1, cb_data);
|
||||
handle_one_reflog_commit(nsha1, cb_data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int handle_one_reflog(const char *path, const unsigned char *sha1, int flag, void *cb_data)
|
||||
{
|
||||
struct all_refs_cb *cb = cb_data;
|
||||
cb->warned_bad_reflog = 0;
|
||||
cb->name_for_errormsg = path;
|
||||
for_each_reflog_ent(path, handle_one_reflog_ent, cb_data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void handle_reflog(struct rev_info *revs, unsigned flags)
|
||||
{
|
||||
struct all_refs_cb cb;
|
||||
cb.all_revs = revs;
|
||||
cb.all_flags = flags;
|
||||
for_each_ref(handle_one_reflog, &cb);
|
||||
}
|
||||
|
||||
static int add_parents_only(struct rev_info *revs, const char *arg, int flags)
|
||||
@ -810,6 +858,10 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
|
||||
handle_all(revs, flags);
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(arg, "--reflog")) {
|
||||
handle_reflog(revs, flags);
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(arg, "--not")) {
|
||||
flags ^= UNINTERESTING;
|
||||
continue;
|
||||
|
Loading…
Reference in New Issue
Block a user