44
static const char *head_name;
45
static void *head_name_to_free;
46
static int sent_capabilities;
47
+static int shallow_update;
48
static const char *alt_shallow_file;
49
50
static enum deny_action parse_deny_action(const char *var, const char *value)
124
return 0;
125
}
126
127
+ if (strcmp(var, "receive.shallowupdate") == 0) {
128
+ shallow_update = git_config_bool(var, value);
129
+ return 0;
130
+ }
131
+
132
return git_default_config(var, value, cb);
133
}
134
429
rp_error("%s", refuse_unconfigured_deny_delete_current_msg[i]);
430
}
431
426
-static const char *update(struct command *cmd)
432
+static int command_singleton_iterator(void *cb_data, unsigned char sha1[20]);
433
+static int update_shallow_ref(struct command *cmd, struct shallow_info *si)
434
+{
435
+ static struct lock_file shallow_lock;
436
+ struct sha1_array extra = SHA1_ARRAY_INIT;
437
+ const char *alt_file;
438
+ uint32_t mask = 1 << (cmd->index % 32);
439
+ int i;
440
+
441
+ trace_printf_key("GIT_TRACE_SHALLOW",
442
+ "shallow: update_shallow_ref %s\n", cmd->ref_name);
443
+ for (i = 0; i < si->shallow->nr; i++)
444
+ if (si->used_shallow[i] &&
445
+ (si->used_shallow[i][cmd->index / 32] & mask) &&
446
+ !delayed_reachability_test(si, i))
447
+ sha1_array_append(&extra, si->shallow->sha1[i]);
448
+
449
+ setup_alternate_shallow(&shallow_lock, &alt_file, &extra);
450
+ if (check_shallow_connected(command_singleton_iterator,
451
+ 0, cmd, alt_file)) {
452
+ rollback_lock_file(&shallow_lock);
453
+ sha1_array_clear(&extra);
454
+ return -1;
455
+ }
456
+
457
+ commit_lock_file(&shallow_lock);
458
+
459
+ /*
460
+ * Make sure setup_alternate_shallow() for the next ref does
461
+ * not lose these new roots..
462
+ */
463
+ for (i = 0; i < extra.nr; i++)
464
+ register_shallow(extra.sha1[i]);
465
+
466
+ si->shallow_ref[cmd->index] = 0;
467
+ sha1_array_clear(&extra);
468
+ return 0;
469
+}
470
+
471
+static const char *update(struct command *cmd, struct shallow_info *si)
472
{
473
const char *name = cmd->ref_name;
474
struct strbuf namespaced_name_buf = STRBUF_INIT;
576
return NULL; /* good */
577
}
578
else {
579
+ if (shallow_update && si->shallow_ref[cmd->index] &&
580
+ update_shallow_ref(cmd, si))
581
+ return "shallow error";
582
+
583
lock = lock_any_ref_for_update(namespaced_name, old_sha1,
584
0, NULL);
585
if (!lock) {
720
return 0;
721
}
722
674
-static void set_connectivity_errors(struct command *commands)
723
+static void set_connectivity_errors(struct command *commands,
724
+ struct shallow_info *si)
725
{
726
struct command *cmd;
727
728
for (cmd = commands; cmd; cmd = cmd->next) {
729
struct command *singleton = cmd;
730
+ if (shallow_update && si->shallow_ref[cmd->index])
731
+ /* to be checked in update_shallow_ref() */
732
+ continue;
733
if (!check_everything_connected(command_singleton_iterator,
734
0, &singleton))
735
continue;
737
}
738
}
739
740
+struct iterate_data {
741
+ struct command *cmds;
742
+ struct shallow_info *si;
743
+};
744
+
745
static int iterate_receive_command_list(void *cb_data, unsigned char sha1[20])
746
{
689
- struct command **cmd_list = cb_data;
747
+ struct iterate_data *data = cb_data;
748
+ struct command **cmd_list = &data->cmds;
749
struct command *cmd = *cmd_list;
750
692
- while (cmd) {
751
+ for (; cmd; cmd = cmd->next) {
752
+ if (shallow_update && data->si->shallow_ref[cmd->index])
753
+ /* to be checked in update_shallow_ref() */
754
+ continue;
755
if (!is_null_sha1(cmd->new_sha1) && !cmd->skip_update) {
756
hashcpy(sha1, cmd->new_sha1);
757
*cmd_list = cmd->next;
758
return 0;
759
}
698
- cmd = cmd->next;
760
}
761
*cmd_list = NULL;
762
return -1; /* end of list */
776
}
777
}
778
718
-static void execute_commands(struct command *commands, const char *unpacker_error)
779
+static void execute_commands(struct command *commands,
780
+ const char *unpacker_error,
781
+ struct shallow_info *si)
782
{
783
+ int checked_connectivity;
784
struct command *cmd;
785
unsigned char sha1[20];
786
+ struct iterate_data data;
787
788
if (unpacker_error) {
789
for (cmd = commands; cmd; cmd = cmd->next)
791
return;
792
}
793
729
- cmd = commands;
730
- if (check_everything_connected(iterate_receive_command_list,
731
- 0, &cmd))
732
- set_connectivity_errors(commands);
794
+ data.cmds = commands;
795
+ data.si = si;
796
+ if (check_everything_connected(iterate_receive_command_list, 0, &data))
797
+ set_connectivity_errors(commands, si);
798
799
reject_updates_to_hidden(commands);
800
811
free(head_name_to_free);
812
head_name = head_name_to_free = resolve_refdup("HEAD", sha1, 0, NULL);
813
814
+ checked_connectivity = 1;
815
for (cmd = commands; cmd; cmd = cmd->next) {
816
if (cmd->error_string)
817
continue;
819
if (cmd->skip_update)
820
continue;
821
756
- cmd->error_string = update(cmd);
822
+ cmd->error_string = update(cmd, si);
823
+ if (shallow_update && !cmd->error_string &&
824
+ si->shallow_ref[cmd->index]) {
825
+ error("BUG: connectivity check has not been run on ref %s",
826
+ cmd->ref_name);
827
+ checked_connectivity = 0;
828
+ }
829
+ }
830
+
831
+ if (shallow_update) {
832
+ if (!checked_connectivity)
833
+ error("BUG: run 'git fsck' for safety.\n"
834
+ "If there are errors, try to remove "
835
+ "the reported refs above");
836
+ if (alt_shallow_file && *alt_shallow_file)
837
+ unlink(alt_shallow_file);
838
}
839
}
840
1005
return ret;
1006
}
1007
1008
+static void prepare_shallow_update(struct command *commands,
1009
+ struct shallow_info *si)
1010
+{
1011
+ int i, j, k, bitmap_size = (si->ref->nr + 31) / 32;
1012
+
1013
+ si->used_shallow = xmalloc(sizeof(*si->used_shallow) *
1014
+ si->shallow->nr);
1015
+ assign_shallow_commits_to_refs(si, si->used_shallow, NULL);
1016
+
1017
+ si->need_reachability_test =
1018
+ xcalloc(si->shallow->nr, sizeof(*si->need_reachability_test));
1019
+ si->reachable =
1020
+ xcalloc(si->shallow->nr, sizeof(*si->reachable));
1021
+ si->shallow_ref = xcalloc(si->ref->nr, sizeof(*si->shallow_ref));
1022
+
1023
+ for (i = 0; i < si->nr_ours; i++)
1024
+ si->need_reachability_test[si->ours[i]] = 1;
1025
+
1026
+ for (i = 0; i < si->shallow->nr; i++) {
1027
+ if (!si->used_shallow[i])
1028
+ continue;
1029
+ for (j = 0; j < bitmap_size; j++) {
1030
+ if (!si->used_shallow[i][j])
1031
+ continue;
1032
+ si->need_reachability_test[i]++;
1033
+ for (k = 0; k < 32; k++)
1034
+ if (si->used_shallow[i][j] & (1 << k))
1035
+ si->shallow_ref[j * 32 + k]++;
1036
+ }
1037
+
1038
+ /*
1039
+ * true for those associated with some refs and belong
1040
+ * in "ours" list aka "step 7 not done yet"
1041
+ */
1042
+ si->need_reachability_test[i] =
1043
+ si->need_reachability_test[i] > 1;
1044
+ }
1045
+
1046
+ /*
1047
+ * keep hooks happy by forcing a temporary shallow file via
1048
+ * env variable because we can't add --shallow-file to every
1049
+ * command. check_everything_connected() will be done with
1050
+ * true .git/shallow though.
1051
+ */
1052
+ setenv(GIT_SHALLOW_FILE_ENVIRONMENT, alt_shallow_file, 1);
1053
+}
1054
+
1055
static void update_shallow_info(struct command *commands,
1056
struct shallow_info *si,
1057
struct sha1_array *ref)
1060
int *ref_status;
1061
remove_nonexistent_theirs_shallow(si);
1062
/* XXX remove_nonexistent_ours_in_pack() */
935
- if (!si->nr_ours && !si->nr_theirs)
1063
+ if (!si->nr_ours && !si->nr_theirs) {
1064
+ shallow_update = 0;
1065
return;
1066
+ }
1067
1068
for (cmd = commands; cmd; cmd = cmd->next) {
1069
if (is_null_sha1(cmd->new_sha1))
1073
}
1074
si->ref = ref;
1075
1076
+ if (shallow_update) {
1077
+ prepare_shallow_update(commands, si);
1078
+ return;
1079
+ }
1080
+
1081
ref_status = xmalloc(sizeof(*ref_status) * ref->nr);
1082
assign_shallow_commits_to_refs(si, NULL, ref_status);
1083
for (cmd = commands; cmd; cmd = cmd->next) {
1199
const char *unpack_status = NULL;
1200
1201
prepare_shallow_info(&si, &shallow);
1202
+ if (!si.nr_ours && !si.nr_theirs)
1203
+ shallow_update = 0;
1204
if (!delete_only(commands)) {
1205
unpack_status = unpack_with_sideband(&si);
1206
update_shallow_info(commands, &si, &ref);
1207
}
1071
- execute_commands(commands, unpack_status);
1208
+ execute_commands(commands, unpack_status, &si);
1209
if (pack_lockfile)
1210
unlink_or_warn(pack_lockfile);
1211
if (report_status)