ref: fa02b11f83544df79b78d7cc364c5a75edbf1bb0
parent: d025a11e327a324ce750d4a8717e422e0911b538
author: glenda <glenda@9front.local>
date: Sat Jun 29 22:20:32 EDT 2019
Implement checking for force pushes
--- a/git.h
+++ b/git.h
@@ -199,6 +199,7 @@
/* object io */
int resolverefs(Hash **, char *);
int resolveref(Hash *, char *);
+Object *ancestor(Object *, Object *);
Object *readobject(Hash);
void parseobject(Object *);
int indexpack(char *, char *, Hash);
--- a/push
+++ b/push
@@ -20,6 +20,7 @@
remote=()
sendall=''
remove=()
+force=()
upstream='origin'
branch=`{awk '$1=="branch"{print $2}' < /mnt/git/ctl}
while(~ $1 -* && ! ~ $1 --){
@@ -35,6 +36,8 @@
case -r;
shift
remove=(-r$1 $remove);
+ case -f;
+ force=-f
case *; usage
}
shift
@@ -51,9 +54,9 @@
exit upstream
}
if(~ $sendall '')
- updates=`$nl{git/send -b $branch $remove $remote}
+ updates=`$nl{git/send $force -b $branch $remove $remote}
if not
- updates=`$nl{git/send $remove -a $remote}
+ updates=`$nl{git/send $force $remove -a $remote}
if(! ~ $status '')
exit $status
--- a/ref.c
+++ b/ref.c
@@ -122,26 +122,17 @@
return h;
}
-int
-ancestor(Eval *ev)
+Object*
+ancestor(Object *a, Object *b)
{
- Object *a, *b, *o, *p;
+ Object *o, *p, *r;
XObject *ht[256];
XObject *h, *q, *q1, *q2;
- int i, r;
+ int i;
- if(ev->nstk < 2){
- werrstr("ancestor needs 2 objects");
- return -1;
- }
- a = pop(ev);
- b = pop(ev);
- if(a == b){
- push(ev, a);
- return 0;
- }
-
- r = -1;
+ if(a == b)
+ return a;
+ r = nil;
memset(ht, 0, sizeof(ht));
q1 = nil;
@@ -166,8 +157,7 @@
h = hnode(ht, p);
if(h->mark != nil){
if(h->mark != q->mark){
- push(ev, h->obj);
- r = 0;
+ r = h->obj;
goto done;
}
} else {
@@ -194,6 +184,25 @@
}
int
+lca(Eval *ev)
+{
+ Object *a, *b, *o;
+
+ if(ev->nstk < 2){
+ werrstr("ancestor needs 2 objects");
+ return -1;
+ }
+ a = pop(ev);
+ b = pop(ev);
+ o = ancestor(a, b);
+ if(o == nil)
+ return -1;
+ push(ev, o);
+ return 0;
+}
+
+
+int
parent(Eval *ev)
{
Object *o, *p;
@@ -349,7 +358,7 @@
break;
case '@':
ev->p++;
- if(ancestor(ev) == -1)
+ if(lca(ev) == -1)
return -1;
break;
default:
--- a/send.c
+++ b/send.c
@@ -32,6 +32,7 @@
};
int sendall;
+int force;
char *curbranch = "refs/heads/master";
char *removed[128];
int nremoved;
@@ -289,6 +290,7 @@
int i, n, r, nupd, nsp, updating;
char buf[65536], *sp[3];
Update *upd, *u;
+ Object *a, *b;
if((nupd = readours(&upd)) == -1)
sysfatal("read refs: %r");
@@ -310,12 +312,17 @@
snprint(u->ref, sizeof(u->ref), sp[1]);
}
+ r = 0;
updating = 0;
for(i = 0; i < nupd; i++){
u = &upd[i];
- if(!hasheq(&u->theirs, &Zhash) && readobject(u->theirs) == nil){
- fprint(2, "remote has diverged: pull and try again\n");
- updating = 0;
+ a = readobject(u->theirs);
+ b = readobject(u->ours);
+ if((!force || hasheq(&u->theirs, &Zhash)) && (a == nil || ancestor(a, b) != a)){
+ fprint(2, "remote has diverged\n");
+ werrstr("force needed");
+ updating=0;
+ r = -1;
break;
}
if(hasheq(&u->ours, &Zhash)){
@@ -348,7 +355,6 @@
updating = 1;
}
flushpkt(fd);
- r = 0;
if(updating){
if(writepack(fd, upd, nupd) == -1)
return -1;
@@ -395,6 +401,7 @@
default: usage(); break;
case 'a': sendall++; break;
case 'd': chattygit++; break;
+ case 'f': force++; break;
case 'r':
if(nremoved == nelem(removed))
sysfatal("too many deleted branches");