Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for deleting files from tree #1678

Merged
merged 7 commits into from
Jun 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 30 additions & 1 deletion src/main/java/org/kohsuke/github/GHTreeBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public class GHTreeBuilder {
// Issue #636: Create Tree no longer accepts null value in sha field
@JsonInclude(Include.NON_NULL)
@SuppressFBWarnings("URF_UNREAD_FIELD")
private static final class TreeEntry {
private static class TreeEntry {

private final String path;
private final String mode;
Expand All @@ -37,6 +37,22 @@ private TreeEntry(String path, String mode, String type) {
}
}

private static class DeleteTreeEntry extends TreeEntry {
/**
* According to reference doc https://docs.github.com/en/rest/git/trees?apiVersion=2022-11-28#create-a-tree: if
* sha value is null then the file will be deleted. That's why in this DTO sha is always {@literal null} and is
* included to json.
*/
@JsonInclude
private final String sha = null;

private DeleteTreeEntry(String path) {
// The `mode` and `type` parameters are required by the API, but their values are ignored during delete.
// Supply reasonable placeholders.
super(path, "100644", "blob");
}
}

/**
* Instantiates a new GH tree builder.
*
Expand Down Expand Up @@ -162,6 +178,19 @@ public GHTreeBuilder add(String path, String content, boolean executable) {
return add(path, content.getBytes(StandardCharsets.UTF_8), executable);
}

/**
* Removes an entry with the given path from base tree.
*
* @param path
* the file path in the tree
* @return this GHTreeBuilder
*/
public GHTreeBuilder delete(String path) {
TreeEntry entry = new DeleteTreeEntry(path);
treeEntries.add(entry);
return this;
}

private String getApiTail() {
return String.format("/repos/%s/%s/git/trees", repo.getOwnerName(), repo.getName());
}
Expand Down
40 changes: 40 additions & 0 deletions src/test/java/org/kohsuke/github/GHTreeBuilderTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,46 @@ public void testAdd() throws Exception {

}

/**
* Test delete.
*
* @throws Exception
* the exception
*/
@Test
public void testDelete() throws Exception {
// add test tree
treeBuilder.add(PATH_README, CONTENT_README, false);
treeBuilder.add(PATH_DATA1, CONTENT_DATA1, false);

GHCommit commit = updateTree();

assertThat(getFileSize(PATH_README), equalTo((long) CONTENT_README.length()));
assertThat(getFileSize(PATH_DATA1), equalTo((long) CONTENT_DATA1.length));

assertThat(commit.getCommitShortInfo().getAuthor().getEmail(), equalTo("[email protected]"));
assertThat(commit.getCommitShortInfo().getCommitter().getEmail(), equalTo("[email protected]"));

// remove a file from tree
mainRef = repo.getRef("heads/main");
treeBuilder = repo.createTree().baseTree(commit.getTree().getSha());
treeBuilder.delete(PATH_DATA1);

GHCommit deleteCommit = updateTree();

assertThat(getFileSize(PATH_README), equalTo((long) CONTENT_README.length()));

assertThat(deleteCommit.getCommitShortInfo().getAuthor().getEmail(), equalTo("[email protected]"));
assertThat(deleteCommit.getCommitShortInfo().getCommitter().getEmail(), equalTo("[email protected]"));

try {
getFileSize(PATH_DATA1);
fail("File " + PATH_DATA1 + " should not exist");
} catch (IOException e) {
assertThat(e.getMessage(), stringContainsInOrder(PATH_DATA1, "Not Found"));
}
}

private GHCommit updateTree() throws IOException {
String treeSha = treeBuilder.create().getSha();
GHCommit commit = new GHCommitBuilder(repo).message("Add files")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
{
"id": 654900107,
"node_id": "R_kgDOJwj7iw",
"name": "GHTreeBuilderTest",
"full_name": "hub4j-test-org/GHTreeBuilderTest",
"private": true,
"owner": {
"login": "hub4j-test-org",
"id": 1793410,
"node_id": "MDQ6VXNlcjE3OTM0MTA=",
"avatar_url": "https://avatars.githubusercontent.com/u/1793410?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/hub4j-test-org",
"html_url": "https://github.com/hub4j-test-org",
"followers_url": "https://api.github.com/users/hub4j-test-org/followers",
"following_url": "https://api.github.com/users/hub4j-test-org/following{/other_user}",
"gists_url": "https://api.github.com/users/hub4j-test-org/gists{/gist_id}",
"starred_url": "https://api.github.com/users/hub4j-test-org/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/hub4j-test-org/subscriptions",
"organizations_url": "https://api.github.com/users/hub4j-test-org/orgs",
"repos_url": "https://api.github.com/users/hub4j-test-org/repos",
"events_url": "https://api.github.com/users/hub4j-test-org/events{/privacy}",
"received_events_url": "https://api.github.com/users/hub4j-test-org/received_events",
"type": "User",
"site_admin": false
},
"html_url": "https://github.com/hub4j-test-org/GHTreeBuilderTest",
"description": null,
"fork": false,
"url": "https://api.github.com/repos/hub4j-test-org/GHTreeBuilderTest",
"forks_url": "https://api.github.com/repos/hub4j-test-org/GHTreeBuilderTest/forks",
"keys_url": "https://api.github.com/repos/hub4j-test-org/GHTreeBuilderTest/keys{/key_id}",
"collaborators_url": "https://api.github.com/repos/hub4j-test-org/GHTreeBuilderTest/collaborators{/collaborator}",
"teams_url": "https://api.github.com/repos/hub4j-test-org/GHTreeBuilderTest/teams",
"hooks_url": "https://api.github.com/repos/hub4j-test-org/GHTreeBuilderTest/hooks",
"issue_events_url": "https://api.github.com/repos/hub4j-test-org/GHTreeBuilderTest/issues/events{/number}",
"events_url": "https://api.github.com/repos/hub4j-test-org/GHTreeBuilderTest/events",
"assignees_url": "https://api.github.com/repos/hub4j-test-org/GHTreeBuilderTest/assignees{/user}",
"branches_url": "https://api.github.com/repos/hub4j-test-org/GHTreeBuilderTest/branches{/branch}",
"tags_url": "https://api.github.com/repos/hub4j-test-org/GHTreeBuilderTest/tags",
"blobs_url": "https://api.github.com/repos/hub4j-test-org/GHTreeBuilderTest/git/blobs{/sha}",
"git_tags_url": "https://api.github.com/repos/hub4j-test-org/GHTreeBuilderTest/git/tags{/sha}",
"git_refs_url": "https://api.github.com/repos/hub4j-test-org/GHTreeBuilderTest/git/refs{/sha}",
"trees_url": "https://api.github.com/repos/hub4j-test-org/GHTreeBuilderTest/git/trees{/sha}",
"statuses_url": "https://api.github.com/repos/hub4j-test-org/GHTreeBuilderTest/statuses/{sha}",
"languages_url": "https://api.github.com/repos/hub4j-test-org/GHTreeBuilderTest/languages",
"stargazers_url": "https://api.github.com/repos/hub4j-test-org/GHTreeBuilderTest/stargazers",
"contributors_url": "https://api.github.com/repos/hub4j-test-org/GHTreeBuilderTest/contributors",
"subscribers_url": "https://api.github.com/repos/hub4j-test-org/GHTreeBuilderTest/subscribers",
"subscription_url": "https://api.github.com/repos/hub4j-test-org/GHTreeBuilderTest/subscription",
"commits_url": "https://api.github.com/repos/hub4j-test-org/GHTreeBuilderTest/commits{/sha}",
"git_commits_url": "https://api.github.com/repos/hub4j-test-org/GHTreeBuilderTest/git/commits{/sha}",
"comments_url": "https://api.github.com/repos/hub4j-test-org/GHTreeBuilderTest/comments{/number}",
"issue_comment_url": "https://api.github.com/repos/hub4j-test-org/GHTreeBuilderTest/issues/comments{/number}",
"contents_url": "https://api.github.com/repos/hub4j-test-org/GHTreeBuilderTest/contents/{+path}",
"compare_url": "https://api.github.com/repos/hub4j-test-org/GHTreeBuilderTest/compare/{base}...{head}",
"merges_url": "https://api.github.com/repos/hub4j-test-org/GHTreeBuilderTest/merges",
"archive_url": "https://api.github.com/repos/hub4j-test-org/GHTreeBuilderTest/{archive_format}{/ref}",
"downloads_url": "https://api.github.com/repos/hub4j-test-org/GHTreeBuilderTest/downloads",
"issues_url": "https://api.github.com/repos/hub4j-test-org/GHTreeBuilderTest/issues{/number}",
"pulls_url": "https://api.github.com/repos/hub4j-test-org/GHTreeBuilderTest/pulls{/number}",
"milestones_url": "https://api.github.com/repos/hub4j-test-org/GHTreeBuilderTest/milestones{/number}",
"notifications_url": "https://api.github.com/repos/hub4j-test-org/GHTreeBuilderTest/notifications{?since,all,participating}",
"labels_url": "https://api.github.com/repos/hub4j-test-org/GHTreeBuilderTest/labels{/name}",
"releases_url": "https://api.github.com/repos/hub4j-test-org/GHTreeBuilderTest/releases{/id}",
"deployments_url": "https://api.github.com/repos/hub4j-test-org/GHTreeBuilderTest/deployments",
"created_at": "2023-06-17T09:21:30Z",
"updated_at": "2023-06-17T09:21:30Z",
"pushed_at": "2023-06-20T05:28:20Z",
"git_url": "git://github.com/hub4j-test-org/GHTreeBuilderTest.git",
"ssh_url": "[email protected]:hub4j-test-org/GHTreeBuilderTest.git",
"clone_url": "https://github.com/hub4j-test-org/GHTreeBuilderTest.git",
"svn_url": "https://github.com/hub4j-test-org/GHTreeBuilderTest",
"homepage": null,
"size": 4,
"stargazers_count": 0,
"watchers_count": 0,
"language": null,
"has_issues": true,
"has_projects": true,
"has_downloads": true,
"has_wiki": false,
"has_pages": false,
"has_discussions": false,
"forks_count": 0,
"mirror_url": null,
"archived": false,
"disabled": false,
"open_issues_count": 0,
"license": null,
"allow_forking": true,
"is_template": false,
"web_commit_signoff_required": false,
"topics": [],
"visibility": "private",
"forks": 0,
"open_issues": 0,
"watchers": 0,
"default_branch": "main",
"permissions": {
"admin": true,
"maintain": true,
"push": true,
"triage": true,
"pull": true
},
"temp_clone_token": "AANV3AUXZXCI3AHCWHMMVFLESE5DS",
"allow_squash_merge": true,
"allow_merge_commit": true,
"allow_rebase_merge": true,
"allow_auto_merge": false,
"delete_branch_on_merge": false,
"allow_update_branch": false,
"use_squash_pr_title_as_default": false,
"squash_merge_commit_message": "COMMIT_MESSAGES",
"squash_merge_commit_title": "COMMIT_OR_PR_TITLE",
"merge_commit_message": "PR_TITLE",
"merge_commit_title": "MERGE_MESSAGE",
"network_count": 0,
"subscribers_count": 1
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
{
"sha": "7e888a1cd95c3caf31a16ff21751a06a7feb039f",
"node_id": "MDY6Q29tbWl0NjU0OTAwMTA3OjdlODg4YTFjZDk1YzNjYWYzMWExNmZmMjE3NTFhMDZhN2ZlYjAzOWY=",
"commit": {
"author": {
"name": "author",
"email": "[email protected]",
"date": "2021-01-23T20:20:25Z"
},
"committer": {
"name": "committer",
"email": "[email protected]",
"date": "2021-01-23T20:20:25Z"
},
"message": "Add files",
"tree": {
"sha": "0efbfcf79def8e437d825e0116def4be6be56026",
"url": "https://api.github.com/repos/hub4j-test-org/GHTreeBuilderTest/git/trees/0efbfcf79def8e437d825e0116def4be6be56026"
},
"url": "https://api.github.com/repos/hub4j-test-org/GHTreeBuilderTest/git/commits/7e888a1cd95c3caf31a16ff21751a06a7feb039f",
"comment_count": 0,
"verification": {
"verified": false,
"reason": "unsigned",
"signature": null,
"payload": null
}
},
"url": "https://api.github.com/repos/hub4j-test-org/GHTreeBuilderTest/commits/7e888a1cd95c3caf31a16ff21751a06a7feb039f",
"html_url": "https://github.com/hub4j-test-org/GHTreeBuilderTest/commit/7e888a1cd95c3caf31a16ff21751a06a7feb039f",
"comments_url": "https://api.github.com/repos/hub4j-test-org/GHTreeBuilderTest/commits/7e888a1cd95c3caf31a16ff21751a06a7feb039f/comments",
"author": null,
"committer": null,
"parents": [
{
"sha": "172349212fb19ffa4f33dcced3263c6963dc750a",
"url": "https://api.github.com/repos/hub4j-test-org/GHTreeBuilderTest/commits/172349212fb19ffa4f33dcced3263c6963dc750a",
"html_url": "https://github.com/hub4j-test-org/GHTreeBuilderTest/commit/172349212fb19ffa4f33dcced3263c6963dc750a"
}
],
"stats": {
"total": 2,
"additions": 2,
"deletions": 0
},
"files": [
{
"sha": "aed2973e4b8a7ff1b30ff5c4751e5a2b38989e74",
"filename": "data/val1.dat",
"status": "added",
"additions": 1,
"deletions": 0,
"changes": 1,
"blob_url": "https://github.com/hub4j-test-org/GHTreeBuilderTest/blob/7e888a1cd95c3caf31a16ff21751a06a7feb039f/data%2Fval1.dat",
"raw_url": "https://github.com/hub4j-test-org/GHTreeBuilderTest/raw/7e888a1cd95c3caf31a16ff21751a06a7feb039f/data%2Fval1.dat",
"contents_url": "https://api.github.com/repos/hub4j-test-org/GHTreeBuilderTest/contents/data%2Fval1.dat?ref=7e888a1cd95c3caf31a16ff21751a06a7feb039f",
"patch": "@@ -0,0 +1 @@\n+\u0001\u0002\u0003\n\\ No newline at end of file"
},
{
"sha": "fbbc875b17d1e17da06b4ee8fda46e2596c41f3c",
"filename": "doc/readme.txt",
"status": "added",
"additions": 1,
"deletions": 0,
"changes": 1,
"blob_url": "https://github.com/hub4j-test-org/GHTreeBuilderTest/blob/7e888a1cd95c3caf31a16ff21751a06a7feb039f/doc%2Freadme.txt",
"raw_url": "https://github.com/hub4j-test-org/GHTreeBuilderTest/raw/7e888a1cd95c3caf31a16ff21751a06a7feb039f/doc%2Freadme.txt",
"contents_url": "https://api.github.com/repos/hub4j-test-org/GHTreeBuilderTest/contents/doc%2Freadme.txt?ref=7e888a1cd95c3caf31a16ff21751a06a7feb039f",
"patch": "@@ -0,0 +1 @@\n+Thanks for using our application!"
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
{
"sha": "7f9b11d9512f639acc6d48439621026cf8410f3a",
"node_id": "MDY6Q29tbWl0NjU0OTAwMTA3OjdmOWIxMWQ5NTEyZjYzOWFjYzZkNDg0Mzk2MjEwMjZjZjg0MTBmM2E=",
"commit": {
"author": {
"name": "author",
"email": "[email protected]",
"date": "2021-01-23T20:20:25Z"
},
"committer": {
"name": "committer",
"email": "[email protected]",
"date": "2021-01-23T20:20:25Z"
},
"message": "Add files",
"tree": {
"sha": "f9a619cb835ac407e0a464618fc59386be70bd63",
"url": "https://api.github.com/repos/hub4j-test-org/GHTreeBuilderTest/git/trees/f9a619cb835ac407e0a464618fc59386be70bd63"
},
"url": "https://api.github.com/repos/hub4j-test-org/GHTreeBuilderTest/git/commits/7f9b11d9512f639acc6d48439621026cf8410f3a",
"comment_count": 0,
"verification": {
"verified": false,
"reason": "unsigned",
"signature": null,
"payload": null
}
},
"url": "https://api.github.com/repos/hub4j-test-org/GHTreeBuilderTest/commits/7f9b11d9512f639acc6d48439621026cf8410f3a",
"html_url": "https://github.com/hub4j-test-org/GHTreeBuilderTest/commit/7f9b11d9512f639acc6d48439621026cf8410f3a",
"comments_url": "https://api.github.com/repos/hub4j-test-org/GHTreeBuilderTest/commits/7f9b11d9512f639acc6d48439621026cf8410f3a/comments",
"author": null,
"committer": null,
"parents": [
{
"sha": "7e888a1cd95c3caf31a16ff21751a06a7feb039f",
"url": "https://api.github.com/repos/hub4j-test-org/GHTreeBuilderTest/commits/7e888a1cd95c3caf31a16ff21751a06a7feb039f",
"html_url": "https://github.com/hub4j-test-org/GHTreeBuilderTest/commit/7e888a1cd95c3caf31a16ff21751a06a7feb039f"
}
],
"stats": {
"total": 1,
"additions": 0,
"deletions": 1
},
"files": [
{
"sha": "aed2973e4b8a7ff1b30ff5c4751e5a2b38989e74",
"filename": "data/val1.dat",
"status": "removed",
"additions": 0,
"deletions": 1,
"changes": 1,
"blob_url": "https://github.com/hub4j-test-org/GHTreeBuilderTest/blob/7e888a1cd95c3caf31a16ff21751a06a7feb039f/data%2Fval1.dat",
"raw_url": "https://github.com/hub4j-test-org/GHTreeBuilderTest/raw/7e888a1cd95c3caf31a16ff21751a06a7feb039f/data%2Fval1.dat",
"contents_url": "https://api.github.com/repos/hub4j-test-org/GHTreeBuilderTest/contents/data%2Fval1.dat?ref=7e888a1cd95c3caf31a16ff21751a06a7feb039f",
"patch": "@@ -1 +0,0 @@\n-\u0001\u0002\u0003\n\\ No newline at end of file"
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"name": "val1.dat",
"path": "data/val1.dat",
"sha": "aed2973e4b8a7ff1b30ff5c4751e5a2b38989e74",
"size": 3,
"url": "https://api.github.com/repos/hub4j-test-org/GHTreeBuilderTest/contents/data/val1.dat?ref=main",
"html_url": "https://github.com/hub4j-test-org/GHTreeBuilderTest/blob/main/data/val1.dat",
"git_url": "https://api.github.com/repos/hub4j-test-org/GHTreeBuilderTest/git/blobs/aed2973e4b8a7ff1b30ff5c4751e5a2b38989e74",
"download_url": "https://raw.githubusercontent.com/hub4j-test-org/GHTreeBuilderTest/main/data/val1.dat?token=AANV3AQG25IMIIRS2WYVBALESE4UY",
"type": "file",
"content": "AQID\n",
"encoding": "base64",
"_links": {
"self": "https://api.github.com/repos/hub4j-test-org/GHTreeBuilderTest/contents/data/val1.dat?ref=main",
"git": "https://api.github.com/repos/hub4j-test-org/GHTreeBuilderTest/git/blobs/aed2973e4b8a7ff1b30ff5c4751e5a2b38989e74",
"html": "https://github.com/hub4j-test-org/GHTreeBuilderTest/blob/main/data/val1.dat"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"name": "readme.txt",
"path": "doc/readme.txt",
"sha": "fbbc875b17d1e17da06b4ee8fda46e2596c41f3c",
"size": 34,
"url": "https://api.github.com/repos/hub4j-test-org/GHTreeBuilderTest/contents/doc/readme.txt?ref=main",
"html_url": "https://github.com/hub4j-test-org/GHTreeBuilderTest/blob/main/doc/readme.txt",
"git_url": "https://api.github.com/repos/hub4j-test-org/GHTreeBuilderTest/git/blobs/fbbc875b17d1e17da06b4ee8fda46e2596c41f3c",
"download_url": "https://raw.githubusercontent.com/hub4j-test-org/GHTreeBuilderTest/main/doc/readme.txt?token=AANV3AUAKUQF4Q66G35XPVLESE4UY",
"type": "file",
"content": "VGhhbmtzIGZvciB1c2luZyBvdXIgYXBwbGljYXRpb24hCg==\n",
"encoding": "base64",
"_links": {
"self": "https://api.github.com/repos/hub4j-test-org/GHTreeBuilderTest/contents/doc/readme.txt?ref=main",
"git": "https://api.github.com/repos/hub4j-test-org/GHTreeBuilderTest/git/blobs/fbbc875b17d1e17da06b4ee8fda46e2596c41f3c",
"html": "https://github.com/hub4j-test-org/GHTreeBuilderTest/blob/main/doc/readme.txt"
}
}
Loading