Radish alpha
r
Radicle web interface
Radicle
Git (anonymous pull)
Log in to clone via SSH
httpd: Add commit diff endpoint
Sebastian Martinez committed 3 years ago
commit 7dabd58aa563c3f1a34d60f8dd4eb4cb389b0c1e
parent fcea4aeb7d8b18738ebafb762af37e69911221a1
2 files changed +393 -108
modified radicle-httpd/src/api/v1/projects.rs
@@ -33,6 +33,7 @@ pub fn router(ctx: Context) -> Router {
        .route("/projects/:project", get(project_handler))
        .route("/projects/:project/commits", get(history_handler))
        .route("/projects/:project/commits/:sha", get(commit_handler))
+
        .route("/projects/:project/diff/:base/:oid", get(diff_handler))
        .route(
            "/projects/:project/activity",
            get(
@@ -230,6 +231,35 @@ async fn commit_handler(
    Ok::<_, Error>(Json(response))
}

+
/// Get diff between two commits
+
/// `GET /projects/:project/diff/:base/:oid`
+
async fn diff_handler(
+
    State(ctx): State<Context>,
+
    Path((project, base, oid)): Path<(Id, Oid, Oid)>,
+
) -> impl IntoResponse {
+
    let storage = &ctx.profile.storage;
+
    let repo = Repository::open(paths::repository(storage, &project))?;
+
    let base = repo.commit(base)?;
+
    let commit = repo.commit(oid)?;
+
    let diff = repo.diff(base.id, commit.id)?;
+

+
    let commits = repo
+
        .history(commit.id)?
+
        .take_while(|c| {
+
            if let Ok(c) = c {
+
                c.id != base.id
+
            } else {
+
                false
+
            }
+
        })
+
        .map(|r| r.map(|c| api::json::commit(&c)))
+
        .collect::<Result<Vec<_>, _>>()?;
+

+
    let response = json!({ "diff": diff, "commits": commits });
+

+
    Ok::<_, Error>(Json(response))
+
}
+

/// Get project activity for the past year.
/// `GET /projects/:project/activity`
async fn activity_handler(
@@ -615,8 +645,8 @@ mod routes {

    use crate::test::{
        self, get, patch, post, CONTRIBUTOR_ISSUE_ID, CONTRIBUTOR_PUB_KEY, CONTRIBUTOR_RID, HEAD,
-
        HEAD_1, ISSUE_COMMENT_ID, ISSUE_DISCUSSION_ID, ISSUE_ID, PATCH_ID, RID, SESSION_ID,
-
        TIMESTAMP,
+
        INITIAL_COMMIT, ISSUE_COMMENT_ID, ISSUE_DISCUSSION_ID, ISSUE_ID, PARENT, PATCH_ID, RID,
+
        SESSION_ID, TIMESTAMP,
    };

    #[tokio::test]
@@ -702,12 +732,31 @@ mod routes {
                    "committer": {
                      "name": "Alice Liddell",
                      "email": "alice@radicle.xyz",
-
                      "time": 1673001014
+
                      "time": 1673003014
                    },
                  },
                  "diff": {
                    "added": [
                      {
+
                        "path": "README",
+
                        "diff": {
+
                          "type": "plain",
+
                          "hunks": [
+
                            {
+
                              "header": "@@ -0,0 +1 @@\n",
+
                              "lines": [
+
                                {
+
                                  "line": "Hello World!\n",
+
                                  "lineNo": 1,
+
                                  "type": "addition",
+
                                },
+
                              ],
+
                            },
+
                          ],
+
                          "eof": "noneMissing",
+
                        },
+
                      },
+
                      {
                        "path": "dir1/README",
                        "diff": {
                          "type": "plain",
@@ -727,14 +776,34 @@ mod routes {
                        }
                      }
                    ],
-
                    "deleted": [],
+
                    "deleted": [
+
                      {
+
                        "path": "CONTRIBUTING",
+
                        "diff": {
+
                          "type": "plain",
+
                          "hunks": [
+
                            {
+
                              "header": "@@ -1 +0,0 @@\n",
+
                              "lines": [
+
                                {
+
                                  "line": "Thank you very much!\n",
+
                                  "lineNo": 1,
+
                                  "type": "deletion",
+
                                },
+
                              ],
+
                            },
+
                          ],
+
                          "eof": "noneMissing",
+
                        },
+
                      },
+
                    ],
                    "moved": [],
                    "copied": [],
                    "modified": [],
                    "stats": {
-
                      "filesChanged": 1,
-
                      "insertions": 1,
-
                      "deletions": 0
+
                      "filesChanged": 3,
+
                      "insertions": 2,
+
                      "deletions": 1
                    }
                  },
                  "branches": [
@@ -743,17 +812,88 @@ mod routes {
                },
                {
                  "commit": {
-
                    "id": HEAD_1,
+
                    "id": PARENT,
                    "author": {
                      "name": "Alice Liddell",
                      "email": "alice@radicle.xyz"
                    },
+
                    "summary": "Add contributing file",
+
                    "description": "",
+
                    "committer": {
+
                      "name": "Alice Liddell",
+
                      "email": "alice@radicle.xyz",
+
                      "time": 1673002014,
+
                    },
+
                  },
+
                  "diff": {
+
                    "added": [
+
                      {
+
                        "path": "CONTRIBUTING",
+
                        "diff": {
+
                          "type": "plain",
+
                          "hunks": [
+
                            {
+
                              "header": "@@ -0,0 +1 @@\n",
+
                              "lines": [
+
                                {
+
                                  "line": "Thank you very much!\n",
+
                                  "lineNo": 1,
+
                                  "type": "addition",
+
                                },
+
                              ],
+
                            },
+
                          ],
+
                          "eof": "noneMissing",
+
                        },
+
                      },
+
                    ],
+
                    "deleted": [
+
                      {
+
                        "path": "README",
+
                        "diff": {
+
                          "type": "plain",
+
                          "hunks": [
+
                            {
+
                              "header": "@@ -1 +0,0 @@\n",
+
                              "lines": [
+
                                {
+
                                  "line": "Hello World!\n",
+
                                  "lineNo": 1,
+
                                  "type": "deletion",
+
                                },
+
                              ],
+
                            },
+
                          ],
+
                          "eof": "noneMissing",
+
                        },
+
                      },
+
                    ],
+
                    "moved": [],
+
                    "copied": [],
+
                    "modified": [],
+
                    "stats": {
+
                      "filesChanged": 2,
+
                      "insertions": 1,
+
                      "deletions": 1,
+
                    },
+
                  },
+
                  "branches": [
+
                    "refs/heads/master",
+
                  ],
+
                },
+
                {
+
                  "commit": {
+
                    "id": INITIAL_COMMIT,
+
                    "author": {
+
                      "name": "Alice Liddell",
+
                      "email": "alice@radicle.xyz",
+
                    },
                    "summary": "Initial commit",
                    "description": "",
                    "committer": {
                      "name": "Alice Liddell",
                      "email": "alice@radicle.xyz",
-
                      "time": 1673001014
+
                      "time": 1673001014,
                    },
                  },
                  "diff": {
@@ -794,11 +934,10 @@ mod routes {
                }
              ],
              "stats": {
-
                "commits": 2,
+
                "commits": 3,
                "branches": 1,
                "contributors": 1
              }
-

            })
        );
    }
@@ -824,12 +963,31 @@ mod routes {
                "committer": {
                  "name": "Alice Liddell",
                  "email": "alice@radicle.xyz",
-
                  "time": 1673001014
+
                  "time": 1673003014
                },
              },
              "diff": {
                "added": [
                  {
+
                    "path": "README",
+
                    "diff": {
+
                        "type": "plain",
+
                        "hunks": [
+
                          {
+
                            "header": "@@ -0,0 +1 @@\n",
+
                            "lines": [
+
                              {
+
                                "line": "Hello World!\n",
+
                                "lineNo": 1,
+
                                "type": "addition",
+
                              },
+
                            ],
+
                          },
+
                        ],
+
                        "eof": "noneMissing",
+
                    },
+
                  },
+
                  {
                    "path": "dir1/README",
                    "diff": {
                      "type": "plain",
@@ -849,14 +1007,34 @@ mod routes {
                    }
                  }
                ],
-
                "deleted": [],
+
                "deleted": [
+
                  {
+
                    "path": "CONTRIBUTING",
+
                    "diff": {
+
                        "type": "plain",
+
                        "hunks": [
+
                          {
+
                            "header": "@@ -1 +0,0 @@\n",
+
                            "lines": [
+
                              {
+
                                "line": "Thank you very much!\n",
+
                                "lineNo": 1,
+
                                "type": "deletion",
+
                              },
+
                            ],
+
                          },
+
                        ],
+
                        "eof": "noneMissing",
+
                    },
+
                  },
+
                ],
                "moved": [],
                "copied": [],
                "modified": [],
                "stats": {
-
                  "filesChanged": 1,
-
                  "insertions": 1,
-
                  "deletions": 0
+
                  "filesChanged": 3,
+
                  "insertions": 2,
+
                  "deletions": 1
                }
              },
              "branches": [
@@ -899,14 +1077,14 @@ mod routes {
                  "committer": {
                    "name": "Alice Liddell",
                    "email": "alice@radicle.xyz",
-
                    "time": 1673001014
+
                    "time": 1673003014
                  },
                },
                "name": "",
                "path": "",
                "stats": {
+
                  "commits": 3,
                  "branches": 1,
-
                  "commits": 2,
                  "contributors": 1
                }
              }
@@ -937,14 +1115,14 @@ mod routes {
                "committer": {
                  "name": "Alice Liddell",
                  "email": "alice@radicle.xyz",
-
                  "time": 1673001014
+
                  "time": 1673003014
                },
              },
              "name": "dir1",
              "path": "dir1",
              "stats": {
                "branches": 1,
-
                "commits": 2,
+
                "commits": 3,
                "contributors": 1
              }
            })
@@ -1006,23 +1184,23 @@ mod routes {
            response.json().await,
            json!({
                "binary": false,
-
                "content": "Hello World!\n",
+
                "name": "README",
+
                "path": "README",
                "lastCommit": {
-
                    "id": HEAD_1,
-
                    "author": {
-
                        "name": "Alice Liddell",
-
                        "email": "alice@radicle.xyz"
-
                    },
-
                    "summary": "Initial commit",
-
                    "description": "",
-
                    "committer": {
-
                        "name": "Alice Liddell",
-
                        "email": "alice@radicle.xyz",
-
                        "time": 1673001014
-
                    },
+
                  "id": HEAD,
+
                  "author": {
+
                    "name": "Alice Liddell",
+
                    "email": "alice@radicle.xyz"
+
                  },
+
                  "summary": "Add another folder",
+
                  "description": "",
+
                  "committer": {
+
                    "name": "Alice Liddell",
+
                    "email": "alice@radicle.xyz",
+
                    "time": 1673003014
+
                  },
                },
-
                "name": "README",
-
                "path": "README"
+
                "content": "Hello World!\n",
            })
        );
    }
@@ -1031,7 +1209,7 @@ mod routes {
    async fn test_projects_readme() {
        let tmp = tempfile::tempdir().unwrap();
        let app = super::router(test::seed(tmp.path()));
-
        let response = get(&app, format!("/projects/{RID}/readme/{HEAD}")).await;
+
        let response = get(&app, format!("/projects/{RID}/readme/{INITIAL_COMMIT}")).await;

        assert_eq!(response.status(), StatusCode::OK);
        assert_eq!(
@@ -1040,21 +1218,101 @@ mod routes {
                "binary": false,
                "content": "Hello World!\n",
                "lastCommit": {
-
                    "id": HEAD_1,
+
                  "id": INITIAL_COMMIT,
+
                  "author": {
+
                    "name": "Alice Liddell",
+
                    "email": "alice@radicle.xyz"
+
                  },
+
                  "summary": "Initial commit",
+
                  "description": "",
+
                  "committer": {
+
                    "name": "Alice Liddell",
+
                    "email": "alice@radicle.xyz",
+
                    "time": 1673001014
+
                  },
+
                },
+
                "name": "README",
+
                "path": "README"
+
            })
+
        );
+
    }
+

+
    #[tokio::test]
+
    async fn test_projects_diff() {
+
        let tmp = tempfile::tempdir().unwrap();
+
        let app = super::router(test::seed(tmp.path()));
+
        let response = get(
+
            &app,
+
            format!("/projects/{RID}/diff/{INITIAL_COMMIT}/{HEAD}"),
+
        )
+
        .await;
+

+
        assert_eq!(response.status(), StatusCode::OK);
+
        assert_eq!(
+
            response.json().await,
+
            json!({
+
                "diff": {
+
                  "added": [
+
                    {
+
                      "path": "dir1/README",
+
                      "diff": {
+
                        "type": "plain",
+
                        "hunks": [
+
                          {
+
                            "header": "@@ -0,0 +1 @@\n",
+
                            "lines": [
+
                              {
+
                                "line": "Hello World from dir1!\n",
+
                                "lineNo": 1,
+
                                "type": "addition",
+
                              },
+
                            ],
+
                          },
+
                        ],
+
                        "eof": "noneMissing",
+
                      },
+
                    },
+
                  ],
+
                  "deleted": [],
+
                  "moved": [],
+
                  "copied": [],
+
                  "modified": [],
+
                  "stats": {
+
                    "filesChanged": 1,
+
                    "insertions": 1,
+
                    "deletions": 0,
+
                  },
+
                },
+
                "commits": [
+
                  {
+
                    "id": HEAD,
                    "author": {
-
                        "name": "Alice Liddell",
-
                        "email": "alice@radicle.xyz"
+
                      "name": "Alice Liddell",
+
                      "email": "alice@radicle.xyz",
                    },
-
                    "summary": "Initial commit",
+
                    "summary": "Add another folder",
                    "description": "",
                    "committer": {
-
                        "name": "Alice Liddell",
-
                        "email": "alice@radicle.xyz",
-
                        "time": 1673001014
+
                      "name": "Alice Liddell",
+
                      "email": "alice@radicle.xyz",
+
                      "time": 1673003014,
                    },
-
                },
-
                "name": "README",
-
                "path": "README"
+
                  },
+
                  {
+
                    "id": PARENT,
+
                    "author": {
+
                      "name": "Alice Liddell",
+
                      "email": "alice@radicle.xyz",
+
                    },
+
                    "summary": "Add contributing file",
+
                    "description": "",
+
                    "committer": {
+
                      "name": "Alice Liddell",
+
                      "email": "alice@radicle.xyz",
+
                      "time": 1673002014,
+
                    }
+
                  }
+
                ],
            })
        );
    }
@@ -1072,18 +1330,18 @@ mod routes {
              {
                "id": ISSUE_ID,
                "author": {
-
                    "id": "did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi"
+
                  "id": "did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi"
                },
                "title": "Issue #1",
                "state": {
-
                    "status": "open"
+
                  "status": "open"
                },
                "assignees": [],
                "discussion": [
                  {
                    "id": ISSUE_ID,
                    "author": {
-
                        "id": "did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi"
+
                      "id": "did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi"
                    },
                    "body": "Change 'hello world' to 'hello everyone'",
                    "reactions": [],
@@ -1140,22 +1398,22 @@ mod routes {
            json!({
              "id": CREATED_ISSUE_ID,
              "author": {
-
                  "id": CONTRIBUTOR_PUB_KEY,
+
                "id": CONTRIBUTOR_PUB_KEY,
              },
              "assignees": [],
              "title": "Issue #2",
              "state": {
-
                  "status": "open",
+
                "status": "open",
              },
              "discussion": [{
-
                  "id": CREATED_ISSUE_ID,
-
                  "author": {
-
                      "id": CONTRIBUTOR_PUB_KEY,
-
                  },
-
                  "body": "Change 'hello world' to 'hello everyone'",
-
                  "reactions": [],
-
                  "timestamp": TIMESTAMP,
-
                  "replyTo": null,
+
                "id": CREATED_ISSUE_ID,
+
                "author": {
+
                  "id": CONTRIBUTOR_PUB_KEY,
+
                },
+
                "body": "Change 'hello world' to 'hello everyone'",
+
                "reactions": [],
+
                "timestamp": TIMESTAMP,
+
                "replyTo": null,
              }],
              "tags": [
                  "bug",
@@ -1203,18 +1461,18 @@ mod routes {
            json!({
              "id": CONTRIBUTOR_ISSUE_ID,
              "author": {
-
                  "id": CONTRIBUTOR_PUB_KEY,
+
                "id": CONTRIBUTOR_PUB_KEY,
              },
              "assignees": [],
              "title": "Issue #1",
              "state": {
-
                  "status": "open",
+
                "status": "open",
              },
              "discussion": [
                {
                  "id": ISSUE_DISCUSSION_ID,
                  "author": {
-
                      "id": CONTRIBUTOR_PUB_KEY,
+
                    "id": CONTRIBUTOR_PUB_KEY,
                  },
                  "body": "Change 'hello world' to 'hello everyone'",
                  "reactions": [],
@@ -1224,7 +1482,7 @@ mod routes {
                {
                  "id": "9685b141c2e939c3d60f8ca34f8c7bf01a609af1",
                  "author": {
-
                      "id": CONTRIBUTOR_PUB_KEY,
+
                    "id": CONTRIBUTOR_PUB_KEY,
                  },
                  "body": "This is first-level comment",
                  "reactions": [],
@@ -1251,7 +1509,8 @@ mod routes {
            "type": "comment",
            "body": "This is a reply to the first comment",
            "replyTo": ISSUE_DISCUSSION_ID,
-
        }}))
+
          }
+
        }))
        .unwrap();

        let _ = get(&app, format!("/projects/{CONTRIBUTOR_RID}/issues")).await;
@@ -1277,18 +1536,18 @@ mod routes {
            json!({
              "id": CONTRIBUTOR_ISSUE_ID,
              "author": {
-
                  "id": CONTRIBUTOR_PUB_KEY,
+
                "id": CONTRIBUTOR_PUB_KEY,
              },
              "assignees": [],
              "title": "Issue #1",
              "state": {
-
                  "status": "open",
+
                "status": "open",
              },
              "discussion": [
                {
                  "id": ISSUE_DISCUSSION_ID,
                  "author": {
-
                      "id": CONTRIBUTOR_PUB_KEY,
+
                    "id": CONTRIBUTOR_PUB_KEY,
                  },
                  "body": "Change 'hello world' to 'hello everyone'",
                  "reactions": [],
@@ -1298,7 +1557,7 @@ mod routes {
                {
                  "id": ISSUE_COMMENT_ID,
                  "author": {
-
                      "id": CONTRIBUTOR_PUB_KEY,
+
                    "id": CONTRIBUTOR_PUB_KEY,
                  },
                  "body": "This is a reply to the first comment",
                  "reactions": [],
@@ -1324,7 +1583,7 @@ mod routes {
              {
                "id": PATCH_ID,
                "author": {
-
                    "id": "did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi"
+
                  "id": "did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi"
                },
                "title": "A new `hello word`",
                "description": "change `hello world` in README to something else",
@@ -1332,16 +1591,16 @@ mod routes {
                "target": "delegates",
                "tags": [],
                "revisions": [
-
                    {
-
                        "id": PATCH_ID,
-
                        "description": "",
-
                        "base": HEAD_1,
-
                        "oid": HEAD,
-
                        "merges": [],
-
                        "discussions": [],
-
                        "timestamp": 1671125284,
-
                        "reviews": [],
-
                    }
+
                  {
+
                    "id": PATCH_ID,
+
                    "description": "",
+
                    "base": PARENT,
+
                    "oid": HEAD,
+
                    "merges": [],
+
                    "discussions": [],
+
                    "timestamp": 1671125284,
+
                    "reviews": [],
+
                  }
                ],
              }
            ])
@@ -1356,7 +1615,7 @@ mod routes {
              {
                "id": PATCH_ID,
                "author": {
-
                    "id": "did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi"
+
                  "id": "did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi"
                },
                "title": "A new `hello word`",
                "description": "change `hello world` in README to something else",
@@ -1364,16 +1623,16 @@ mod routes {
                "target": "delegates",
                "tags": [],
                "revisions": [
-
                    {
-
                        "id": PATCH_ID,
-
                        "description": "",
-
                        "base": HEAD_1,
-
                        "oid": HEAD,
-
                        "merges": [],
-
                        "discussions": [],
-
                        "timestamp": 1671125284,
-
                        "reviews": [],
-
                    }
+
                  {
+
                    "id": PATCH_ID,
+
                    "description": "",
+
                    "base": PARENT,
+
                    "oid": HEAD,
+
                    "merges": [],
+
                    "discussions": [],
+
                    "timestamp": 1671125284,
+
                    "reviews": [],
+
                  }
                ],
              }
            )
@@ -1382,7 +1641,7 @@ mod routes {

    #[tokio::test]
    async fn test_projects_create_patches() {
-
        const CREATED_PATCH_ID: &str = "9170195973fb145b327b1f5cd728a6e46b3bb082";
+
        const CREATED_PATCH_ID: &str = "f69641cba6d7df2c22844d7f39225b5cda54d363";

        let tmp = tempfile::tempdir().unwrap();
        let ctx = test::contributor(tmp.path());
@@ -1393,7 +1652,7 @@ mod routes {
        let body = serde_json::to_vec(&json!({
          "title": "Update README",
          "description": "Do some changes to README",
-
          "target": HEAD_1,
+
          "target": INITIAL_COMMIT,
          "oid": HEAD,
          "tags": [],
        }))
@@ -1431,7 +1690,7 @@ mod routes {
              {
                "id": CREATED_PATCH_ID,
                "author": {
-
                    "id": CONTRIBUTOR_PUB_KEY
+
                  "id": CONTRIBUTOR_PUB_KEY
                },
                "title": "Update README",
                "description": "Do some changes to README",
@@ -1439,16 +1698,16 @@ mod routes {
                "target": "delegates",
                "tags": [],
                "revisions": [
-
                    {
-
                        "id": CREATED_PATCH_ID,
-
                        "description": "",
-
                        "base": HEAD_1,
-
                        "oid": HEAD,
-
                        "merges": [],
-
                        "discussions": [],
-
                        "timestamp": 1671125284,
-
                        "reviews": [],
-
                    }
+
                  {
+
                    "id": CREATED_PATCH_ID,
+
                    "description": "",
+
                    "base": INITIAL_COMMIT,
+
                    "oid": HEAD,
+
                    "merges": [],
+
                    "discussions": [],
+
                    "timestamp": 1671125284,
+
                    "reviews": [],
+
                  }
                ],
              }
            )
modified radicle-httpd/src/test.rs
@@ -24,9 +24,10 @@ use radicle_crypto::test::signer::MockSigner;
use crate::api::{auth, Context};

pub const RID: &str = "rad:z4FucBZHZMCsxTyQE1dfE2YR59Qbp";
-
pub const HEAD: &str = "1e978d19f251cd9821d9d9a76d1bd436bf0690d5";
-
pub const HEAD_1: &str = "f604ce9fd5b7cc77b7609beda45ea8760bee78f7";
-
pub const PATCH_ID: &str = "6ec9a764a888576abc7e582dbf82a31e23a9789d";
+
pub const HEAD: &str = "e8c676b9e3b42308dc9d218b70faa5408f8e58ca";
+
pub const PARENT: &str = "ee8d6a29304623a78ebfa5eeed5af674d0e58f83";
+
pub const INITIAL_COMMIT: &str = "f604ce9fd5b7cc77b7609beda45ea8760bee78f7";
+
pub const PATCH_ID: &str = "a6afa179631163169bf9fb0921229317ec3950af";
pub const ISSUE_ID: &str = "5ad77fa3f476beed9a26f49b2b3b844e61bef792";
pub const ISSUE_DISCUSSION_ID: &str = "f1dff128a22e8183a23516dd9812e72e80914c92";
pub const ISSUE_COMMENT_ID: &str = "845218041bf9eb8155bfa4aaa8f0c91ce18e5c13";
@@ -100,6 +101,29 @@ fn seed_with_signer<G: Signer>(dir: &Path, profile: radicle::Profile, signer: &G

    repo.checkout_tree(tree.as_object(), None).unwrap();

+
    let tree = radicle::git::write_tree(
+
        Path::new("CONTRIBUTING"),
+
        "Thank you very much!\n".as_bytes(),
+
        &repo,
+
    )
+
    .unwrap();
+
    let sig_time = git2::Time::new(1673002014, 0);
+
    let sig = git2::Signature::new("Alice Liddell", "alice@radicle.xyz", &sig_time).unwrap();
+

+
    let oid2 = repo
+
        .commit(
+
            Some("HEAD"),
+
            &sig,
+
            &sig,
+
            "Add contributing file\n",
+
            &tree,
+
            &[&commit],
+
        )
+
        .unwrap();
+
    let commit2 = repo.find_commit(oid2).unwrap();
+

+
    repo.checkout_tree(tree.as_object(), None).unwrap();
+

    fs::create_dir(workdir.join("dir1")).unwrap();
    fs::write(
        workdir.join("dir1").join("README"),
@@ -115,13 +139,15 @@ fn seed_with_signer<G: Signer>(dir: &Path, profile: radicle::Profile, signer: &G
    let oid = index.write_tree().unwrap();
    let tree = repo.find_tree(oid).unwrap();

+
    let sig_time = git2::Time::new(1673003014, 0);
+
    let sig = git2::Signature::new("Alice Liddell", "alice@radicle.xyz", &sig_time).unwrap();
    repo.commit(
        Some("HEAD"),
        &sig,
        &sig,
        "Add another folder\n",
        &tree,
-
        &[&commit],
+
        &[&commit2],
    )
    .unwrap();

@@ -149,7 +175,7 @@ fn seed_with_signer<G: Signer>(dir: &Path, profile: radicle::Profile, signer: &G
    // eq. rad patch open
    let mut patches = Patches::open(&repo).unwrap();
    let oid = radicle::git::Oid::from_str(HEAD).unwrap();
-
    let base = radicle::git::Oid::from_str(HEAD_1).unwrap();
+
    let base = radicle::git::Oid::from_str(PARENT).unwrap();
    let _ = patches
        .create(
            "A new `hello word`",