cli: Add canonical remote to `init` and `checkout`
Add a remote that points to the canonical upstream.
This commit is contained in:
parent
d6cebf613f
commit
6346931ce2
|
|
@ -12,8 +12,9 @@ $ cat .git/config
|
||||||
filemode = true
|
filemode = true
|
||||||
logallrefupdates = true
|
logallrefupdates = true
|
||||||
[remote "rad"]
|
[remote "rad"]
|
||||||
url = rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji/z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
|
url = rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji
|
||||||
fetch = +refs/heads/*:refs/remotes/rad/*
|
fetch = +refs/heads/*:refs/remotes/rad/*
|
||||||
|
pushurl = rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji/z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
|
||||||
[branch "master"]
|
[branch "master"]
|
||||||
remote = rad
|
remote = rad
|
||||||
merge = refs/heads/master
|
merge = refs/heads/master
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,9 @@ $ cat .git/config
|
||||||
precomposeunicode = true
|
precomposeunicode = true
|
||||||
logallrefupdates = true
|
logallrefupdates = true
|
||||||
[remote "rad"]
|
[remote "rad"]
|
||||||
url = rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji/z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
|
url = rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji
|
||||||
fetch = +refs/heads/*:refs/remotes/rad/*
|
fetch = +refs/heads/*:refs/remotes/rad/*
|
||||||
|
pushurl = rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji/z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
|
||||||
[branch "master"]
|
[branch "master"]
|
||||||
remote = rad
|
remote = rad
|
||||||
merge = refs/heads/master
|
merge = refs/heads/master
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ Check the remote configuration:
|
||||||
|
|
||||||
```
|
```
|
||||||
$ git remote --verbose
|
$ git remote --verbose
|
||||||
rad rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji/z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi (fetch)
|
rad rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji (fetch)
|
||||||
rad rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji/z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi (push)
|
rad rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji/z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi (push)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ We can also take a look at the remotes:
|
||||||
|
|
||||||
```
|
```
|
||||||
$ git remote -v
|
$ git remote -v
|
||||||
rad rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji/z6Mkt67GdsW7715MEfRuP4pSZxJRJh6kj6Y48WRqVv4N1tRk (fetch)
|
rad rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji (fetch)
|
||||||
rad rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji/z6Mkt67GdsW7715MEfRuP4pSZxJRJh6kj6Y48WRqVv4N1tRk (push)
|
rad rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji/z6Mkt67GdsW7715MEfRuP4pSZxJRJh6kj6Y48WRqVv4N1tRk (push)
|
||||||
z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji/z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi (fetch)
|
z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji/z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi (fetch)
|
||||||
z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji/z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi (push)
|
z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji/z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi (push)
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,9 @@ Now, we can see that there is a new remote in the list of remotes:
|
||||||
|
|
||||||
```
|
```
|
||||||
$ rad remote list
|
$ rad remote list
|
||||||
❲fetch❳ bob z6Mkt67GdsW7715MEfRuP4pSZxJRJh6kj6Y48WRqVv4N1tRk
|
bob z6Mkt67GdsW7715MEfRuP4pSZxJRJh6kj6Y48WRqVv4N1tRk (fetch)
|
||||||
❲fetch❳ rad z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
|
rad the canonical upstream (fetch)
|
||||||
|
rad z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi (push)
|
||||||
```
|
```
|
||||||
|
|
||||||
You can see both `bob` and `rad` as remotes. The `rad` remote is our personal remote of the project.
|
You can see both `bob` and `rad` as remotes. The `rad` remote is our personal remote of the project.
|
||||||
|
|
@ -28,10 +29,3 @@ Now, add another time `bob` but without specify the `name`, so we should be able
|
||||||
$ rad remote add did:key:z6Mkt67GdsW7715MEfRuP4pSZxJRJh6kj6Y48WRqVv4N1tRk
|
$ rad remote add did:key:z6Mkt67GdsW7715MEfRuP4pSZxJRJh6kj6Y48WRqVv4N1tRk
|
||||||
✓ Remote bob added with rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji/z6Mkt67GdsW7715MEfRuP4pSZxJRJh6kj6Y48WRqVv4N1tRk
|
✓ Remote bob added with rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji/z6Mkt67GdsW7715MEfRuP4pSZxJRJh6kj6Y48WRqVv4N1tRk
|
||||||
```
|
```
|
||||||
|
|
||||||
and then we remove again remote just added
|
|
||||||
|
|
||||||
```
|
|
||||||
$ rad remote rm bob
|
|
||||||
✓ Remote `bob` removed
|
|
||||||
```
|
|
||||||
|
|
|
||||||
|
|
@ -1,54 +0,0 @@
|
||||||
To create a local copy of a repository on the radicle network, we use the
|
|
||||||
`clone` command, followed by the identifier or *RID* of the repository:
|
|
||||||
|
|
||||||
```
|
|
||||||
$ rad clone rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji
|
|
||||||
✓ Tracking relationship established for rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji
|
|
||||||
✓ Fetching rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji from z6MknSL…StBU8Vi..
|
|
||||||
✓ Forking under z6Mkt67…v4N1tRk..
|
|
||||||
✓ Creating checkout in ./heartwood..
|
|
||||||
✓ Remote z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi created
|
|
||||||
✓ Remote-tracking branch z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi/master created for z6MknSL…StBU8Vi
|
|
||||||
✓ Repository successfully cloned under [..]/heartwood/
|
|
||||||
```
|
|
||||||
|
|
||||||
We can now have a look at the new working copy that was created from the cloned
|
|
||||||
repository:
|
|
||||||
|
|
||||||
```
|
|
||||||
$ cd heartwood
|
|
||||||
$ ls
|
|
||||||
README
|
|
||||||
$ cat README
|
|
||||||
Hello World!
|
|
||||||
```
|
|
||||||
|
|
||||||
Let's check that the remote tracking branch was setup correctly:
|
|
||||||
|
|
||||||
```
|
|
||||||
$ git branch --remotes
|
|
||||||
rad/master
|
|
||||||
z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi/master
|
|
||||||
```
|
|
||||||
|
|
||||||
The first branch is ours, and the second points to the repository delegate.
|
|
||||||
We can also take a look at the remotes:
|
|
||||||
|
|
||||||
```
|
|
||||||
$ git remote -v
|
|
||||||
rad rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji/z6Mkt67GdsW7715MEfRuP4pSZxJRJh6kj6Y48WRqVv4N1tRk (fetch)
|
|
||||||
rad rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji/z6Mkt67GdsW7715MEfRuP4pSZxJRJh6kj6Y48WRqVv4N1tRk (push)
|
|
||||||
z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji/z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi (fetch)
|
|
||||||
z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi rad://z42hL2jL4XNk6K8oHQaSWfMgCL7ji/z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi (push)
|
|
||||||
```
|
|
||||||
|
|
||||||
Finally, let's inspect the last commit!
|
|
||||||
|
|
||||||
```
|
|
||||||
$ git log -n 1
|
|
||||||
commit f2de534b5e81d7c6e2dcaf58c3dd91573c0a0354
|
|
||||||
Author: anonymous <anonymous@radicle.xyz>
|
|
||||||
Date: Mon Jan 1 14:39:16 2018 +0000
|
|
||||||
|
|
||||||
Second commit
|
|
||||||
```
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
../rad-clone.md
|
||||||
|
|
@ -86,3 +86,9 @@ $ rad patch --merged
|
||||||
│ ✓ merged by did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi (you) [ ... ]│
|
│ ✓ merged by did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi (you) [ ... ]│
|
||||||
╰───────────────────────────────────────────────────────────────────────────────────────────────╯
|
╰───────────────────────────────────────────────────────────────────────────────────────────────╯
|
||||||
```
|
```
|
||||||
|
|
||||||
|
To publish our new state to the network, we simply push:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ git push
|
||||||
|
```
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
Now that the patch is merged, we can update our master branch to the canonical
|
||||||
|
master, which includes our patch.
|
||||||
|
|
||||||
|
First, we confirm that our master is behind:
|
||||||
|
```
|
||||||
|
$ git rev-parse master
|
||||||
|
f2de534b5e81d7c6e2dcaf58c3dd91573c0a0354
|
||||||
|
```
|
||||||
|
|
||||||
|
Then, we call `rad sync --fetch` to fetch from the maintainer:
|
||||||
|
```
|
||||||
|
$ rad sync --fetch
|
||||||
|
✓ Fetching rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji from z6MknSL…StBU8Vi..
|
||||||
|
✓ Fetched repository from 1 seed(s)
|
||||||
|
```
|
||||||
|
|
||||||
|
Now let's checkout `master` and pull the maintainer's changes:
|
||||||
|
```
|
||||||
|
$ git checkout master
|
||||||
|
Your branch is up to date with 'rad/master'.
|
||||||
|
$ git pull --all
|
||||||
|
Fetching rad
|
||||||
|
Fetching z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
|
||||||
|
Updating f2de534..f6484e0
|
||||||
|
Fast-forward
|
||||||
|
README.md | 0
|
||||||
|
REQUIREMENTS.md | 0
|
||||||
|
2 files changed, 0 insertions(+), 0 deletions(-)
|
||||||
|
create mode 100644 README.md
|
||||||
|
create mode 100644 REQUIREMENTS.md
|
||||||
|
```
|
||||||
|
|
||||||
|
Now our master branch is up to date with the maintainer's master:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ git rev-parse master
|
||||||
|
f6484e0f43e48a8983b9b39bf9bd4cd889f1d520
|
||||||
|
$ git diff master..z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi/master
|
||||||
|
```
|
||||||
|
|
@ -3,33 +3,26 @@ use radicle_term::{Element, Table};
|
||||||
use crate::git;
|
use crate::git;
|
||||||
use crate::terminal as term;
|
use crate::terminal as term;
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn format_direction(d: &git::Direction) -> String {
|
|
||||||
match d {
|
|
||||||
git::Direction::Fetch => "fetch".to_owned(),
|
|
||||||
git::Direction::Push => "push".to_owned(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn run(repo: &git::Repository) -> anyhow::Result<()> {
|
pub fn run(repo: &git::Repository) -> anyhow::Result<()> {
|
||||||
let mut table = Table::default();
|
let mut table = Table::default();
|
||||||
let remotes = git::rad_remotes(repo)?;
|
let remotes = git::rad_remotes(repo)?;
|
||||||
for r in remotes {
|
for r in remotes {
|
||||||
for spec in r.refspecs() {
|
for (dir, url) in [("fetch", Some(r.url)), ("push", r.pushurl)] {
|
||||||
let dir = spec.direction();
|
let Some(url) = url else {
|
||||||
let url = r.url.clone();
|
continue;
|
||||||
let name = r.name.clone();
|
};
|
||||||
let nid_row = url.namespace.map_or(
|
let nid = url.namespace.map_or(
|
||||||
term::format::dim("This is the canonical upstream".to_string()),
|
term::format::dim("the canonical upstream".to_string()).italic(),
|
||||||
|namespace| term::format::highlight(namespace.to_string()),
|
|namespace| term::format::tertiary(namespace.to_string()),
|
||||||
);
|
);
|
||||||
table.push([
|
table.push([
|
||||||
term::format::badge_positive(format_direction(&dir)),
|
term::format::bold(r.name.clone()),
|
||||||
term::format::highlight(name.to_owned()),
|
nid,
|
||||||
nid_row,
|
term::format::parens(term::format::secondary(dir.to_owned())),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
table.print();
|
table.print();
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -76,13 +76,10 @@ pub enum RemoteError {
|
||||||
pub struct Remote<'a> {
|
pub struct Remote<'a> {
|
||||||
pub(crate) name: String,
|
pub(crate) name: String,
|
||||||
pub(crate) url: radicle::git::Url,
|
pub(crate) url: radicle::git::Url,
|
||||||
inner: git2::Remote<'a>,
|
pub(crate) pushurl: Option<radicle::git::Url>,
|
||||||
}
|
|
||||||
|
|
||||||
impl Remote<'_> {
|
#[allow(dead_code)]
|
||||||
pub fn refspecs(&self) -> git2::Refspecs {
|
inner: git2::Remote<'a>,
|
||||||
self.inner.refspecs()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> TryFrom<git2::Remote<'a>> for Remote<'a> {
|
impl<'a> TryFrom<git2::Remote<'a>> for Remote<'a> {
|
||||||
|
|
@ -92,10 +89,16 @@ impl<'a> TryFrom<git2::Remote<'a>> for Remote<'a> {
|
||||||
let url = value.url().map_or(Err(RemoteError::MissingUrl), |url| {
|
let url = value.url().map_or(Err(RemoteError::MissingUrl), |url| {
|
||||||
Ok(radicle::git::Url::from_str(url)?)
|
Ok(radicle::git::Url::from_str(url)?)
|
||||||
})?;
|
})?;
|
||||||
|
let pushurl = value
|
||||||
|
.pushurl()
|
||||||
|
.map(radicle::git::Url::from_str)
|
||||||
|
.transpose()?;
|
||||||
let name = value.name().ok_or(RemoteError::MissingName)?;
|
let name = value.name().ok_or(RemoteError::MissingName)?;
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
name: name.to_owned(),
|
name: name.to_owned(),
|
||||||
url,
|
url,
|
||||||
|
pushurl,
|
||||||
inner: value,
|
inner: value,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ impl<'a> SetupRemote<'a> {
|
||||||
/// Run the setup for the given peer.
|
/// Run the setup for the given peer.
|
||||||
pub fn run(&self, node: NodeId) -> anyhow::Result<Option<(Remote, RefString)>> {
|
pub fn run(&self, node: NodeId) -> anyhow::Result<Option<(Remote, RefString)>> {
|
||||||
let url = radicle::git::Url::from(self.project).with_namespace(node);
|
let url = radicle::git::Url::from(self.project).with_namespace(node);
|
||||||
let mut remote = radicle::git::configure_remote(self.repo, &node.to_string(), &url)?;
|
let mut remote = radicle::git::configure_remote(self.repo, &node.to_string(), &url, &url)?;
|
||||||
|
|
||||||
// Fetch the refs into the working copy.
|
// Fetch the refs into the working copy.
|
||||||
if self.fetch {
|
if self.fetch {
|
||||||
|
|
|
||||||
|
|
@ -769,4 +769,12 @@ fn rad_workflow() {
|
||||||
[],
|
[],
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
test(
|
||||||
|
"examples/workflow/6-pulling-contributor.md",
|
||||||
|
&working.join("bob").join("heartwood"),
|
||||||
|
Some(&bob.home),
|
||||||
|
[],
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -375,10 +375,12 @@ pub fn write_tree<'r>(
|
||||||
pub fn configure_remote<'r>(
|
pub fn configure_remote<'r>(
|
||||||
repo: &'r git2::Repository,
|
repo: &'r git2::Repository,
|
||||||
name: &str,
|
name: &str,
|
||||||
url: &Url,
|
fetch: &Url,
|
||||||
|
push: &Url,
|
||||||
) -> Result<git2::Remote<'r>, git2::Error> {
|
) -> Result<git2::Remote<'r>, git2::Error> {
|
||||||
let fetch = format!("+refs/heads/*:refs/remotes/{name}/*");
|
let fetchspec = format!("+refs/heads/*:refs/remotes/{name}/*");
|
||||||
let remote = repo.remote_with_fetch(name, url.to_string().as_str(), &fetch)?;
|
let remote = repo.remote_with_fetch(name, fetch.to_string().as_str(), &fetchspec)?;
|
||||||
|
repo.remote_set_pushurl(name, Some(push.to_string().as_str()))?;
|
||||||
|
|
||||||
Ok(remote)
|
Ok(remote)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -70,9 +70,9 @@ pub fn init<G: Signer, S: WriteStorage>(
|
||||||
})?;
|
})?;
|
||||||
let doc = identity::Doc::initial(proj, delegate).verified()?;
|
let doc = identity::Doc::initial(proj, delegate).verified()?;
|
||||||
let (project, _) = Repository::init(&doc, pk, storage, signer)?;
|
let (project, _) = Repository::init(&doc, pk, storage, signer)?;
|
||||||
let url = git::Url::from(project.id).with_namespace(*pk);
|
let url = git::Url::from(project.id);
|
||||||
|
|
||||||
git::configure_remote(repo, &REMOTE_NAME, &url)?;
|
git::configure_remote(repo, &REMOTE_NAME, &url, &url.clone().with_namespace(*pk))?;
|
||||||
git::push(
|
git::push(
|
||||||
repo,
|
repo,
|
||||||
&REMOTE_NAME,
|
&REMOTE_NAME,
|
||||||
|
|
@ -221,10 +221,15 @@ pub fn checkout<P: AsRef<Path>, S: storage::ReadStorage>(
|
||||||
opts.no_reinit(true).description(project.description());
|
opts.no_reinit(true).description(project.description());
|
||||||
|
|
||||||
let repo = git2::Repository::init_opts(path.as_ref(), &opts)?;
|
let repo = git2::Repository::init_opts(path.as_ref(), &opts)?;
|
||||||
let url = git::Url::from(proj).with_namespace(*remote);
|
let url = git::Url::from(proj);
|
||||||
|
|
||||||
// Configure and fetch all refs from remote.
|
// Configure and fetch all refs from remote.
|
||||||
git::configure_remote(&repo, &REMOTE_NAME, &url)?;
|
git::configure_remote(
|
||||||
|
&repo,
|
||||||
|
&REMOTE_NAME,
|
||||||
|
&url,
|
||||||
|
&url.clone().with_namespace(*remote),
|
||||||
|
)?;
|
||||||
git::fetch(&repo, &REMOTE_NAME).map_err(CheckoutError::Fetch)?;
|
git::fetch(&repo, &REMOTE_NAME).map_err(CheckoutError::Fetch)?;
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue