cli: Check for branch on checkout
The `rad patch checkout` command would blindly create a branch when being executed. If there was a branch already existing and user had committed to that branch, switched without updating the patch, and then switched back, then they would lose the commit on that branch -- the original commit of the patch would be taken instead. Fix this by first checking if the branch existed beforehand, and setting the workspace to use that branch's commit. Add a test to ensure that this works as expected. Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com> X-Clacks-Overhead: GNU Terry Pratchett
This commit is contained in:
parent
90f3a37a08
commit
7e3c7a7ae0
|
|
@ -0,0 +1,72 @@
|
|||
We may want to work on top of an existing patch and this where `rad
|
||||
patch checkout` comes into play. So, first we will create a patch to
|
||||
set up the workflow.
|
||||
|
||||
```
|
||||
$ git checkout -b flux-capacitor-power
|
||||
$ touch REQUIREMENTS
|
||||
```
|
||||
|
||||
Here the instructions are added to the project's README for 1.21 gigawatts and
|
||||
commit the changes to git.
|
||||
|
||||
```
|
||||
$ git add REQUIREMENTS
|
||||
$ git commit -v -m "Define power requirements"
|
||||
[flux-capacitor-power 3e674d1] Define power requirements
|
||||
1 file changed, 0 insertions(+), 0 deletions(-)
|
||||
create mode 100644 REQUIREMENTS
|
||||
```
|
||||
|
||||
Once the code is ready, we open (or create) a patch with our changes for the project.
|
||||
|
||||
``` (stderr)
|
||||
$ git push rad -o patch.message="Define power requirements" -o patch.message="See details." HEAD:refs/patches
|
||||
✓ Patch a8926643a8f6a65bc386b0131621994000485d4d opened
|
||||
To rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji/z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
|
||||
* [new reference] HEAD -> refs/patches
|
||||
```
|
||||
|
||||
Now, let's checkout the patch that we just created:
|
||||
|
||||
```
|
||||
$ rad patch checkout a892664
|
||||
✓ Switched to branch patch/a892664
|
||||
✓ Branch patch/a892664 setup to track rad/patches/a8926643a8f6a65bc386b0131621994000485d4d
|
||||
```
|
||||
|
||||
Now, let's add a README too!
|
||||
|
||||
```
|
||||
$ touch README.md
|
||||
$ git add README.md
|
||||
$ git commit --message "Add README, just for the fun"
|
||||
[patch/a892664 27857ec] Add README, just for the fun
|
||||
1 file changed, 0 insertions(+), 0 deletions(-)
|
||||
create mode 100644 README.md
|
||||
```
|
||||
|
||||
But maybe we first wanted to rebase `master` so we ended up being on
|
||||
that branch:
|
||||
|
||||
``` (stderr)
|
||||
$ git checkout master
|
||||
Switched to branch 'master'
|
||||
```
|
||||
|
||||
We can be safe in the knowledge that our changes on the
|
||||
`patch/a892664` branch are still safe:
|
||||
|
||||
```
|
||||
$ rad patch checkout a892664
|
||||
✓ Switched to branch patch/a892664
|
||||
```
|
||||
|
||||
We can now finish off the update:
|
||||
|
||||
``` (stderr)
|
||||
$ git push rad -o patch.message="Add README, just for the fun"
|
||||
✓ Patch a892664 updated to 8d8aa0887a11f2a37fa8ed0d5723efa96fd727ed
|
||||
To rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji/z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
|
||||
3e674d1..27857ec patch/a892664 -> patches/a8926643a8f6a65bc386b0131621994000485d4d
|
||||
```
|
||||
|
|
@ -34,11 +34,20 @@ pub fn run(
|
|||
let patch_branch =
|
||||
// SAFETY: Patch IDs are valid refstrings.
|
||||
git::refname!("patch").join(RefString::try_from(term::format::cob(&patch_id)).unwrap());
|
||||
let commit = find_patch_commit(revision, stored, working)?;
|
||||
|
||||
// Create patch branch and switch to it.
|
||||
working.branch(patch_branch.as_str(), &commit, true)?;
|
||||
working.checkout_tree(commit.as_object(), None)?;
|
||||
match working.find_branch(patch_branch.as_str(), radicle::git::raw::BranchType::Local) {
|
||||
Ok(branch) => {
|
||||
let commit = branch.get().peel_to_commit()?;
|
||||
working.checkout_tree(commit.as_object(), None)?;
|
||||
}
|
||||
Err(e) if radicle::git::is_not_found_err(&e) => {
|
||||
let commit = find_patch_commit(revision, stored, working)?;
|
||||
// Create patch branch and switch to it.
|
||||
working.branch(patch_branch.as_str(), &commit, true)?;
|
||||
working.checkout_tree(commit.as_object(), None)?;
|
||||
}
|
||||
Err(e) => return Err(e.into()),
|
||||
}
|
||||
working.set_head(&git::refs::workdir::branch(&patch_branch))?;
|
||||
|
||||
spinner.message(format!(
|
||||
|
|
|
|||
|
|
@ -410,6 +410,26 @@ fn rad_patch() {
|
|||
test("examples/rad-patch.md", working.path(), Some(home), []).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rad_patch_checkout() {
|
||||
let mut environment = Environment::new();
|
||||
let profile = environment.profile("alice");
|
||||
let working = tempfile::tempdir().unwrap();
|
||||
let home = &profile.home;
|
||||
|
||||
// Setup a test repository.
|
||||
fixtures::repository(working.path());
|
||||
|
||||
test("examples/rad-init.md", working.path(), Some(home), []).unwrap();
|
||||
test(
|
||||
"examples/rad-patch-checkout.md",
|
||||
working.path(),
|
||||
Some(home),
|
||||
[],
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rad_patch_update() {
|
||||
let mut environment = Environment::new();
|
||||
|
|
|
|||
Loading…
Reference in New Issue