Skip to content

Commit 56502ad

Browse files
authored
ability to delete remote branch (#838)
* added ability to delete remote branch (closes #622)
1 parent 62ea1de commit 56502ad

File tree

14 files changed

+261
-58
lines changed

14 files changed

+261
-58
lines changed

asyncgit/src/push.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ pub struct PushRequest {
2222
///
2323
pub force: bool,
2424
///
25+
pub delete: bool,
26+
///
2527
pub basic_credential: Option<BasicAuthCredential>,
2628
}
2729

@@ -98,6 +100,7 @@ impl AsyncPush {
98100
params.remote.as_str(),
99101
params.branch.as_str(),
100102
params.force,
103+
params.delete,
101104
params.basic_credential.clone(),
102105
Some(progress_sender.clone()),
103106
);

asyncgit/src/sync/branch/merge_commit.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ mod test {
134134
"origin",
135135
"master",
136136
false,
137+
false,
137138
None,
138139
None,
139140
)
@@ -151,7 +152,7 @@ mod test {
151152

152153
//push should fail since origin diverged
153154
assert!(push(
154-
clone2_dir, "origin", "master", false, None, None,
155+
clone2_dir, "origin", "master", false, false, None, None,
155156
)
156157
.is_err());
157158

@@ -222,6 +223,7 @@ mod test {
222223
"origin",
223224
"master",
224225
false,
226+
false,
225227
None,
226228
None,
227229
)

asyncgit/src/sync/branch/merge_ff.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ pub mod test {
8080
"origin",
8181
"master",
8282
false,
83+
false,
8384
None,
8485
None,
8586
)
@@ -103,6 +104,7 @@ pub mod test {
103104
"origin",
104105
"master",
105106
false,
107+
false,
106108
None,
107109
None,
108110
)

asyncgit/src/sync/branch/merge_rebase.rs

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,10 @@ mod test {
107107

108108
assert_eq!(clone1.head_detached().unwrap(), false);
109109

110-
push(clone1_dir, "origin", "master", false, None, None)
111-
.unwrap();
110+
push(
111+
clone1_dir, "origin", "master", false, false, None, None,
112+
)
113+
.unwrap();
112114

113115
assert_eq!(clone1.head_detached().unwrap(), false);
114116

@@ -129,8 +131,10 @@ mod test {
129131

130132
assert_eq!(clone2.head_detached().unwrap(), false);
131133

132-
push(clone2_dir, "origin", "master", false, None, None)
133-
.unwrap();
134+
push(
135+
clone2_dir, "origin", "master", false, false, None, None,
136+
)
137+
.unwrap();
134138

135139
assert_eq!(clone2.head_detached().unwrap(), false);
136140

@@ -201,8 +205,10 @@ mod test {
201205
Time::new(0, 0),
202206
);
203207

204-
push(clone1_dir, "origin", "master", false, None, None)
205-
.unwrap();
208+
push(
209+
clone1_dir, "origin", "master", false, false, None, None,
210+
)
211+
.unwrap();
206212

207213
// clone2
208214

@@ -219,8 +225,10 @@ mod test {
219225
Time::new(1, 0),
220226
);
221227

222-
push(clone2_dir, "origin", "master", false, None, None)
223-
.unwrap();
228+
push(
229+
clone2_dir, "origin", "master", false, false, None, None,
230+
)
231+
.unwrap();
224232

225233
// clone1
226234

@@ -278,8 +286,10 @@ mod test {
278286
let _commit1 =
279287
write_commit_file(&clone1, "test.txt", "test", "commit1");
280288

281-
push(clone1_dir, "origin", "master", false, None, None)
282-
.unwrap();
289+
push(
290+
clone1_dir, "origin", "master", false, false, None, None,
291+
)
292+
.unwrap();
283293

284294
// clone2
285295

@@ -295,8 +305,10 @@ mod test {
295305
"commit2",
296306
);
297307

298-
push(clone2_dir, "origin", "master", false, None, None)
299-
.unwrap();
308+
push(
309+
clone2_dir, "origin", "master", false, false, None, None,
310+
)
311+
.unwrap();
300312

301313
// clone1
302314

asyncgit/src/sync/branch/mod.rs

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -471,7 +471,8 @@ mod tests_branches {
471471

472472
write_commit_file(&repo, "f1.txt", "foo", "c1");
473473
rename_branch(dir, "refs/heads/master", branch_name).unwrap();
474-
push(dir, "origin", branch_name, false, None, None).unwrap();
474+
push(dir, "origin", branch_name, false, false, None, None)
475+
.unwrap();
475476
}
476477

477478
#[test]
@@ -680,14 +681,17 @@ mod test_remote_branches {
680681

681682
write_commit_file(&clone1, "test.txt", "test", "commit1");
682683

683-
push(clone1_dir, "origin", "master", false, None, None)
684-
.unwrap();
684+
push(
685+
clone1_dir, "origin", "master", false, false, None, None,
686+
)
687+
.unwrap();
685688

686689
create_branch(clone1_dir, "foo").unwrap();
687690

688691
write_commit_file(&clone1, "test.txt", "test2", "commit2");
689692

690-
push(clone1_dir, "origin", "foo", false, None, None).unwrap();
693+
push(clone1_dir, "origin", "foo", false, false, None, None)
694+
.unwrap();
691695

692696
// clone2
693697

@@ -719,11 +723,14 @@ mod test_remote_branches {
719723
// clone1
720724

721725
write_commit_file(&clone1, "test.txt", "test", "commit1");
722-
push(clone1_dir, "origin", "master", false, None, None)
723-
.unwrap();
726+
push(
727+
clone1_dir, "origin", "master", false, false, None, None,
728+
)
729+
.unwrap();
724730
create_branch(clone1_dir, "foo").unwrap();
725731
write_commit_file(&clone1, "test.txt", "test2", "commit2");
726-
push(clone1_dir, "origin", "foo", false, None, None).unwrap();
732+
push(clone1_dir, "origin", "foo", false, false, None, None)
733+
.unwrap();
727734

728735
// clone2
729736

asyncgit/src/sync/remotes/push.rs

Lines changed: 116 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ pub(crate) fn push(
9595
remote: &str,
9696
branch: &str,
9797
force: bool,
98+
delete: bool,
9899
basic_credential: Option<BasicAuthCredential>,
99100
progress_sender: Option<Sender<ProgressNotification>>,
100101
) -> Result<()> {
@@ -109,15 +110,15 @@ pub(crate) fn push(
109110
options.remote_callbacks(callbacks.callbacks());
110111
options.packbuilder_parallelism(0);
111112

112-
let branch_name = format!("refs/heads/{}", branch);
113-
if force {
114-
remote.push(
115-
&[String::from("+") + &branch_name],
116-
Some(&mut options),
117-
)?;
118-
} else {
119-
remote.push(&[branch_name.as_str()], Some(&mut options))?;
120-
}
113+
let branch_modifier = match (force, delete) {
114+
(true, true) => "+:",
115+
(false, true) => ":",
116+
(true, false) => "+",
117+
(false, false) => "",
118+
};
119+
let branch_name =
120+
format!("{}refs/heads/{}", branch_modifier, branch);
121+
remote.push(&[branch_name.as_str()], Some(&mut options))?;
121122

122123
if let Some((reference, msg)) =
123124
callbacks.get_stats()?.push_rejected_msg
@@ -128,7 +129,9 @@ pub(crate) fn push(
128129
)));
129130
}
130131

131-
branch_set_upstream(&repo, branch)?;
132+
if !delete {
133+
branch_set_upstream(&repo, branch)?;
134+
}
132135

133136
Ok(())
134137
}
@@ -138,7 +141,10 @@ mod tests {
138141
use super::*;
139142
use crate::sync::{
140143
self,
141-
tests::{get_commit_ids, repo_init, repo_init_bare},
144+
tests::{
145+
get_commit_ids, repo_clone, repo_init, repo_init_bare,
146+
write_commit_file,
147+
},
142148
};
143149
use git2::Repository;
144150
use std::{fs::File, io::Write, path::Path};
@@ -148,7 +154,6 @@ mod tests {
148154
// This test mimics the scenario of 2 people having 2
149155
// local branches and both modifying the same file then
150156
// both pushing, sequentially
151-
152157
let (tmp_repo_dir, repo) = repo_init().unwrap();
153158
let (tmp_other_repo_dir, other_repo) = repo_init().unwrap();
154159
let (tmp_upstream_dir, _) = repo_init_bare().unwrap();
@@ -183,6 +188,7 @@ mod tests {
183188
"origin",
184189
"master",
185190
false,
191+
false,
186192
None,
187193
None,
188194
)
@@ -208,6 +214,7 @@ mod tests {
208214
"origin",
209215
"master",
210216
false,
217+
false,
211218
None,
212219
None,
213220
)
@@ -223,6 +230,7 @@ mod tests {
223230
"origin",
224231
"master",
225232
true,
233+
false,
226234
None,
227235
None,
228236
)
@@ -291,6 +299,7 @@ mod tests {
291299
"origin",
292300
"master",
293301
false,
302+
false,
294303
None,
295304
None,
296305
)
@@ -333,6 +342,7 @@ mod tests {
333342
"origin",
334343
"master",
335344
false,
345+
false,
336346
None,
337347
None,
338348
)
@@ -353,6 +363,7 @@ mod tests {
353363
"origin",
354364
"master",
355365
true,
366+
false,
356367
None,
357368
None,
358369
)
@@ -372,4 +383,97 @@ mod tests {
372383
.id();
373384
assert_eq!(new_upstream_parent, repo_2_parent,);
374385
}
386+
387+
#[test]
388+
fn test_delete_remote_branch() {
389+
// This test mimics the scenario of a user creating a branch, push it, and then remove it on the remote
390+
391+
let (upstream_dir, upstream_repo) = repo_init_bare().unwrap();
392+
393+
let (tmp_repo_dir, repo) =
394+
repo_clone(upstream_dir.path().to_str().unwrap())
395+
.unwrap();
396+
397+
// You need a commit before being able to branch !
398+
let commit_1 = write_commit_file(
399+
&repo,
400+
"temp_file.txt",
401+
"SomeContent",
402+
"Initial commit",
403+
);
404+
405+
let commits = get_commit_ids(&repo, 1);
406+
assert!(commits.contains(&commit_1));
407+
408+
push(
409+
tmp_repo_dir.path().to_str().unwrap(),
410+
"origin",
411+
"master",
412+
false,
413+
false,
414+
None,
415+
None,
416+
)
417+
.unwrap();
418+
419+
// Create the local branch
420+
sync::create_branch(
421+
tmp_repo_dir.path().to_str().unwrap(),
422+
"test_branch",
423+
)
424+
.unwrap();
425+
426+
// Push the local branch
427+
push(
428+
tmp_repo_dir.path().to_str().unwrap(),
429+
"origin",
430+
"test_branch",
431+
false,
432+
false,
433+
None,
434+
None,
435+
)
436+
.unwrap();
437+
438+
// Test if the branch exits on the remote
439+
assert_eq!(
440+
upstream_repo
441+
.branches(None)
442+
.unwrap()
443+
.map(|i| i.unwrap())
444+
.map(|(i, _)| i.name().unwrap().unwrap().to_string())
445+
.filter(|i| i == "test_branch")
446+
.next()
447+
.is_some(),
448+
true
449+
);
450+
451+
// Delete the remote branch
452+
assert_eq!(
453+
push(
454+
tmp_repo_dir.path().to_str().unwrap(),
455+
"origin",
456+
"test_branch",
457+
false,
458+
true,
459+
None,
460+
None,
461+
)
462+
.is_ok(),
463+
true
464+
);
465+
466+
// Test that the branch has be remove from the remote
467+
assert_eq!(
468+
upstream_repo
469+
.branches(None)
470+
.unwrap()
471+
.map(|i| i.unwrap())
472+
.map(|(i, _)| i.name().unwrap().unwrap().to_string())
473+
.filter(|i| i == "test_branch")
474+
.next()
475+
.is_some(),
476+
false
477+
);
478+
}
375479
}

0 commit comments

Comments
 (0)