#include "revision.h"
#include "grep.h"
#include "reflog-walk.h"
+#include "patch-ids.h"
static char *path_name(struct name_path *path, const char *name)
{
}
void add_pending_object(struct rev_info *revs, struct object *obj, const char *name)
+{
+ add_pending_object_with_mode(revs, obj, name, S_IFINVALID);
+}
+
+void add_pending_object_with_mode(struct rev_info *revs, struct object *obj, const char *name, unsigned mode)
{
if (revs->no_walk && (obj->flags & UNINTERESTING))
die("object ranges do not make sense when not walking revisions");
- add_object_array(obj, name, &revs->pending);
+ add_object_array_with_mode(obj, name, &revs->pending, mode);
if (revs->reflog_info && obj->type == OBJ_COMMIT)
add_reflog_for_walk(revs->reflog_info,
(struct commit *)obj, name);
}
}
+static void cherry_pick_list(struct commit_list *list)
+{
+ struct commit_list *p;
+ int left_count = 0, right_count = 0;
+ int left_first;
+ struct patch_ids ids;
+
+ /* First count the commits on the left and on the right */
+ for (p = list; p; p = p->next) {
+ struct commit *commit = p->item;
+ unsigned flags = commit->object.flags;
+ if (flags & BOUNDARY)
+ ;
+ else if (flags & SYMMETRIC_LEFT)
+ left_count++;
+ else
+ right_count++;
+ }
+
+ left_first = left_count < right_count;
+ init_patch_ids(&ids);
+
+ /* Compute patch-ids for one side */
+ for (p = list; p; p = p->next) {
+ struct commit *commit = p->item;
+ unsigned flags = commit->object.flags;
+
+ if (flags & BOUNDARY)
+ continue;
+ /*
+ * If we have fewer left, left_first is set and we omit
+ * commits on the right branch in this loop. If we have
+ * fewer right, we skip the left ones.
+ */
+ if (left_first != !!(flags & SYMMETRIC_LEFT))
+ continue;
+ commit->util = add_commit_patch_id(commit, &ids);
+ }
+
+ /* Check the other side */
+ for (p = list; p; p = p->next) {
+ struct commit *commit = p->item;
+ struct patch_id *id;
+ unsigned flags = commit->object.flags;
+
+ if (flags & BOUNDARY)
+ continue;
+ /*
+ * If we have fewer left, left_first is set and we omit
+ * commits on the left branch in this loop.
+ */
+ if (left_first == !!(flags & SYMMETRIC_LEFT))
+ continue;
+
+ /*
+ * Have we seen the same patch id?
+ */
+ id = has_commit_patch_id(commit, &ids);
+ if (!id)
+ continue;
+ id->seen = 1;
+ commit->object.flags |= SHOWN;
+ }
+
+ /* Now check the original side for seen ones */
+ for (p = list; p; p = p->next) {
+ struct commit *commit = p->item;
+ struct patch_id *ent;
+
+ ent = commit->util;
+ if (!ent)
+ continue;
+ if (ent->seen)
+ commit->object.flags |= SHOWN;
+ commit->util = NULL;
+ }
+
+ free_patch_ids(&ids);
+}
+
static void limit_list(struct rev_info *revs)
{
struct commit_list *list = revs->commits;
continue;
p = &commit_list_insert(commit, p)->next;
}
+ if (revs->cherry_pick)
+ cherry_pick_list(newlist);
+
revs->commits = newlist;
}
revs->min_age = -1;
revs->skip_count = -1;
revs->max_count = -1;
+ revs->subject_prefix = "PATCH";
revs->prune_fn = NULL;
revs->prune_data = NULL;
int flags,
int cant_be_filename)
{
+ unsigned mode;
char *dotdot;
struct object *object;
unsigned char sha1[20];
local_flags = UNINTERESTING;
arg++;
}
- if (get_sha1(arg, sha1))
+ if (get_sha1_with_mode(arg, sha1, &mode))
return -1;
if (!cant_be_filename)
verify_non_filename(revs->prefix, arg);
object = get_reference(revs, arg, sha1, flags ^ local_flags);
- add_pending_object(revs, object, arg);
+ add_pending_object_with_mode(revs, object, arg, mode);
return 0;
}
revs->left_right = 1;
continue;
}
+ if (!strcmp(arg, "--cherry-pick")) {
+ revs->cherry_pick = 1;
+ continue;
+ }
if (!strcmp(arg, "--objects")) {
revs->tag_objects = 1;
revs->tree_objects = 1;
continue;
}
if (!strcmp(arg, "--relative-date")) {
- revs->relative_date = 1;
+ revs->date_mode = DATE_RELATIVE;
+ continue;
+ }
+ if (!strncmp(arg, "--date=", 7)) {
+ if (!strcmp(arg + 7, "relative"))
+ revs->date_mode = DATE_RELATIVE;
+ else if (!strcmp(arg + 7, "local"))
+ revs->date_mode = DATE_LOCAL;
+ else if (!strcmp(arg + 7, "default"))
+ revs->date_mode = DATE_NORMAL;
+ else
+ die("unknown date format %s", arg);
continue;
}
if (def && !revs->pending.nr) {
unsigned char sha1[20];
struct object *object;
- if (get_sha1(def, sha1))
+ unsigned mode;
+ if (get_sha1_with_mode(def, sha1, &mode))
die("bad default revision '%s'", def);
object = get_reference(revs, def, sha1, 0);
- add_pending_object(revs, object, def);
+ add_pending_object_with_mode(revs, object, def, mode);
}
if (revs->topo_order)