Skip to content

Commit deb7f02

Browse files
Support cross workspace amend
Change: ws-amend
1 parent fa8a7e0 commit deb7f02

File tree

4 files changed

+285
-8
lines changed

4 files changed

+285
-8
lines changed

josh-core/src/history.rs

+16-1
Original file line numberDiff line numberDiff line change
@@ -440,7 +440,22 @@ pub fn unapply_filter(
440440
let tree = module_commit.tree()?;
441441
let commit_message = module_commit.summary().unwrap_or("NO COMMIT MESSAGE");
442442

443-
let new_trees: JoshResult<Vec<_>> = {
443+
let mut nt = None;
444+
if let Some(change_ids) = change_ids {
445+
for c in change_ids.iter() {
446+
let cid = get_change_id(&module_commit, ret);
447+
448+
if c.id == cid.id {
449+
let x = transaction.repo().find_commit(c.commit)?;
450+
nt = Some(filter::unapply(transaction, filter, tree.clone(), x.tree()?)?.id());
451+
break;
452+
}
453+
}
454+
}
455+
456+
let new_trees: JoshResult<Vec<_>> = if let Some(nt) = nt {
457+
Ok(vec![nt])
458+
} else {
444459
let span = tracing::span!(
445460
tracing::Level::TRACE,
446461
"unapply filter",

josh-core/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ pub struct Change {
5353
}
5454

5555
impl Change {
56-
fn new(commit: git2::Oid) -> Self {
56+
pub fn new(commit: git2::Oid) -> Self {
5757
Self {
5858
author: Default::default(),
5959
id: Default::default(),

josh-proxy/src/lib.rs

+46-6
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,14 @@ pub fn process_repo_update(repo_update: RepoUpdate) -> josh::JoshResult<String>
219219
None
220220
};
221221

222+
if changes.is_some() && push_mode == PushMode::Review {
223+
changes = Some(refs_to_changes(
224+
&transaction_mirror,
225+
&baseref.replacen("refs/heads/", "", 1),
226+
&author,
227+
));
228+
}
229+
222230
let filterobj = josh::filter::parse(&repo_update.filter_spec)?;
223231
let new_oid = git2::Oid::from_str(new)?;
224232
let backward_new_oid = {
@@ -814,6 +822,38 @@ impl Drop for TmpGitNamespace {
814822
}
815823
}
816824

825+
fn refs_to_changes(
826+
transaction: &josh::cache::Transaction,
827+
baseref: &str,
828+
change_author: &str,
829+
) -> Vec<josh::Change> {
830+
let mut changes = vec![];
831+
let glob = transaction.refname(&format!(
832+
"refs/heads/@changes/{}/{}/*",
833+
baseref, change_author
834+
));
835+
836+
for r in transaction.repo().references_glob(&glob).unwrap() {
837+
let r = r.unwrap();
838+
let mut change = josh::Change::new(r.target().unwrap());
839+
change.author = change_author.to_string();
840+
841+
let id = r.name().unwrap().replacen(
842+
&transaction.refname(&format!(
843+
"refs/heads/@changes/{}/{}/",
844+
baseref, change_author
845+
)),
846+
"",
847+
1,
848+
);
849+
change.id = Some(id);
850+
851+
changes.push(change);
852+
}
853+
854+
return changes;
855+
}
856+
817857
fn changes_to_refs(
818858
baseref: &str,
819859
change_author: &str,
@@ -833,12 +873,12 @@ fn changes_to_refs(
833873
if id.contains('@') {
834874
return Err(josh::josh_error("Change id must not contain '@'"));
835875
}
836-
if seen.contains(&id) {
837-
return Err(josh::josh_error(&format!(
838-
"rejecting to push {:?} with duplicate label",
839-
change.commit
840-
)));
841-
}
876+
//if seen.contains(&id) {
877+
// return Err(josh::josh_error(&format!(
878+
// "rejecting to push {:?} with duplicate label",
879+
// change.commit
880+
// )));
881+
//}
842882
seen.push(id);
843883
} else {
844884
return Err(josh::josh_error(&format!(

tests/proxy/push_gerrit_amend.t

+222
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,222 @@
1+
$ . ${TESTDIR}/setup_test_env.sh
2+
$ cd ${TESTTMP}
3+
4+
$ git clone -q http://localhost:8001/real_repo.git 1> /dev/null
5+
warning: You appear to have cloned an empty repository.
6+
$ cd real_repo
7+
8+
$ mkdir sub1
9+
$ mkdir sub2
10+
$ echo contents1 > sub1/file1
11+
$ echo contents2 > sub2/file2
12+
$ git add .
13+
$ git commit -m "add files" 1> /dev/null
14+
$ git push 1> /dev/null
15+
To http://localhost:8001/real_repo.git
16+
* [new branch] master -> master
17+
18+
$ cd ${TESTTMP}
19+
20+
$ git clone -q http://localhost:8002/real_repo.git:/sub1.git sub1
21+
$ cd sub1
22+
23+
$ echo contents1_new > file1
24+
$ git add file1
25+
$ git commit -m "Change-Id: 1234" 1> /dev/null
26+
$ git log --decorate --graph --pretty="%s %d"
27+
* Change-Id: 1234 (HEAD -> master)
28+
* add files (origin/master, origin/HEAD)
29+
$ git push -o author=josh@example.com origin master:refs/for/master
30+
remote: josh-proxy
31+
remote: response from upstream:
32+
remote: To http://localhost:8001/real_repo.git
33+
remote: * [new branch] 1234 -> @changes/master/josh@example.com/1234
34+
remote: To http://localhost:8001/real_repo.git
35+
remote: * [new reference] JOSH_PUSH -> refs/for/master
36+
remote: To http://localhost:8001/real_repo.git
37+
remote: * [new branch] master -> @heads/master/josh@example.com
38+
remote:
39+
remote:
40+
To http://localhost:8002/real_repo.git:/sub1.git
41+
* [new reference] master -> refs/for/master
42+
43+
$ cd ${TESTTMP}/real_repo
44+
$ git fetch origin
45+
From http://localhost:8001/real_repo
46+
* [new branch] @changes/master/josh@example.com/1234 -> origin/@changes/master/josh@example.com/1234
47+
* [new branch] @heads/master/josh@example.com -> origin/@heads/master/josh@example.com
48+
$ git diff origin/@changes/master/josh@example.com/1234~1..origin/@changes/master/josh@example.com/1234
49+
diff --git a/sub1/file1 b/sub1/file1
50+
index a024003..70a938d 100644
51+
--- a/sub1/file1
52+
+++ b/sub1/file1
53+
@@ -1 +1 @@
54+
-contents1
55+
+contents1_new
56+
57+
$ cd ${TESTTMP}
58+
$ git clone -q http://localhost:8002/real_repo.git:/sub2.git sub2
59+
$ cd sub2
60+
$ git log --decorate --graph --pretty="%s %d"
61+
* add files (HEAD -> master, origin/master, origin/HEAD, origin/@heads/master/josh@example.com, origin/@changes/master/josh@example.com/1234)
62+
63+
$ echo contents2_new > file2
64+
$ git add file2
65+
$ git commit -m "Change-Id: 1234" 1> /dev/null
66+
$ git push http://localhost:8001/real_repo.git :refs/for/master
67+
To http://localhost:8001/real_repo.git
68+
- [deleted] refs/for/master
69+
$ git push -o author=josh@example.com origin master:refs/for/master
70+
remote: josh-proxy
71+
remote: response from upstream:
72+
remote: Everything up-to-date
73+
remote: To http://localhost:8001/real_repo.git
74+
remote: + 9b69fe2...920a7be 1234 -> @changes/master/josh@example.com/1234 (forced update)
75+
remote: To http://localhost:8001/real_repo.git
76+
remote: * [new reference] JOSH_PUSH -> refs/for/master
77+
remote: To http://localhost:8001/real_repo.git
78+
remote: + 9b69fe2...920a7be master -> @heads/master/josh@example.com (forced update)
79+
remote:
80+
remote:
81+
To http://localhost:8002/real_repo.git:/sub2.git
82+
* [new reference] master -> refs/for/master
83+
84+
$ cd ${TESTTMP}/real_repo
85+
$ git fetch origin
86+
From http://localhost:8001/real_repo
87+
+ 9b69fe2...920a7be @changes/master/josh@example.com/1234 -> origin/@changes/master/josh@example.com/1234 (forced update)
88+
+ 9b69fe2...920a7be @heads/master/josh@example.com -> origin/@heads/master/josh@example.com (forced update)
89+
$ git diff origin/@changes/master/josh@example.com/1234~1..origin/@changes/master/josh@example.com/1234
90+
diff --git a/sub1/file1 b/sub1/file1
91+
index a024003..70a938d 100644
92+
--- a/sub1/file1
93+
+++ b/sub1/file1
94+
@@ -1 +1 @@
95+
-contents1
96+
+contents1_new
97+
diff --git a/sub2/file2 b/sub2/file2
98+
index 6b46faa..72e4684 100644
99+
--- a/sub2/file2
100+
+++ b/sub2/file2
101+
@@ -1 +1 @@
102+
-contents2
103+
+contents2_new
104+
105+
$ curl -s http://localhost:8002/flush
106+
Flushed credential cache
107+
$ git fetch origin
108+
109+
Make sure all temporary namespace got removed
110+
$ tree ${TESTTMP}/remote/scratch/real_repo.git/refs/ | grep request_
111+
[1]
112+
113+
$ bash ${TESTDIR}/destroy_test_env.sh
114+
"real_repo.git" = [
115+
":/sub1",
116+
":/sub2",
117+
"::sub1/",
118+
"::sub2/",
119+
]
120+
.
121+
|-- josh
122+
| `-- 18
123+
| `-- sled
124+
| |-- blobs
125+
| |-- conf
126+
| `-- db
127+
|-- mirror
128+
| |-- FETCH_HEAD
129+
| |-- HEAD
130+
| |-- config
131+
| |-- description
132+
| |-- info
133+
| | `-- exclude
134+
| |-- objects
135+
| | |-- 3d
136+
| | | `-- 77ff51363c9825cc2a221fc0ba5a883a1a2c72
137+
| | |-- 63
138+
| | | `-- 7d3debfcb3bdadc2ebd92e6451bcb34aebcec1
139+
| | |-- 6b
140+
| | | `-- 46faacade805991bcaea19382c9d941828ce80
141+
| | |-- 70
142+
| | | `-- a938dff577e016189da58f38b71cf0ab3d4cbb
143+
| | |-- 95
144+
| | | `-- 3f19a771cbc2937546fec3b0b155fd2ffe26be
145+
| | |-- 9b
146+
| | | |-- 13ff5c153ca4bc05cb337ad4dfcfe4ffe7af46
147+
| | | `-- 69fe244c5e0cbc08d2aba426f1ce639ab4e017
148+
| | |-- a0
149+
| | | `-- 24003ee1acc6bf70318a46e7b6df651b9dc246
150+
| | |-- ae
151+
| | | `-- a557394ce29f000108607abd97f19fed4d1b7c
152+
| | |-- ca
153+
| | | `-- 77fb80b683ebe1fd4d4d6c2dee5d247f9befee
154+
| | |-- info
155+
| | `-- pack
156+
| `-- refs
157+
| |-- heads
158+
| |-- josh
159+
| | `-- upstream
160+
| | `-- real_repo.git
161+
| | |-- HEAD
162+
| | `-- refs
163+
| | `-- heads
164+
| | |-- @changes
165+
| | | `-- master
166+
| | | `-- josh@example.com
167+
| | | `-- 1234
168+
| | |-- @heads
169+
| | | `-- master
170+
| | | `-- josh@example.com
171+
| | `-- master
172+
| `-- tags
173+
`-- overlay
174+
|-- HEAD
175+
|-- config
176+
|-- description
177+
|-- info
178+
| `-- exclude
179+
|-- objects
180+
| |-- 19
181+
| | `-- 4865382d22d1f0b6bc65029c74833d4509d6cd
182+
| |-- 25
183+
| | `-- f54a31709f8520b0798c743ee1efcbe47069ce
184+
| |-- 29
185+
| | `-- 7ce4243f24c3ce36b47ed90b1e6b788937c633
186+
| |-- 31
187+
| | `-- 8ff73ef0235d761f6aee1194a6bdaaeb1d0923
188+
| |-- 52
189+
| | `-- be19f48566b18ccf49846b221d84f0b75cae66
190+
| |-- 63
191+
| | `-- 7d3debfcb3bdadc2ebd92e6451bcb34aebcec1
192+
| |-- 6c
193+
| | `-- 94de87e1c04cbb8292abe90fc419c51113cfc2
194+
| |-- 70
195+
| | `-- a938dff577e016189da58f38b71cf0ab3d4cbb
196+
| |-- 72
197+
| | `-- e468401514da24f311bbc90908bff97b3f503a
198+
| |-- 78
199+
| | `-- 94b7b9ac2a655147a5c0935002ea977b99d83d
200+
| |-- 92
201+
| | `-- 0a7beb2c682ae84bdb9cd786a1bdd38891bced
202+
| |-- 9b
203+
| | |-- 13ff5c153ca4bc05cb337ad4dfcfe4ffe7af46
204+
| | `-- 69fe244c5e0cbc08d2aba426f1ce639ab4e017
205+
| |-- a7
206+
| | `-- 8fae76b871ddf5473364d136f384d9613df3e7
207+
| |-- b6
208+
| | `-- 44f072c8707dc0a051ae120591d312973787dc
209+
| |-- c8
210+
| | `-- 2fc150c43f13cc56c0e9caeba01b58ec612022
211+
| |-- info
212+
| `-- pack
213+
`-- refs
214+
|-- heads
215+
|-- namespaces
216+
`-- tags
217+
218+
56 directories, 41 files
219+
220+
$ cat ${TESTTMP}/josh-proxy.out
221+
$ cat ${TESTTMP}/josh-proxy.out | grep REPO_UPDATE
222+
$ cat ${TESTTMP}/josh-proxy.out | grep "==="

0 commit comments

Comments
 (0)