Skip to content

Commit

Permalink
Handle remote branches
Browse files Browse the repository at this point in the history
  • Loading branch information
gschier committed Feb 7, 2025
1 parent 2da898d commit a42bee0
Show file tree
Hide file tree
Showing 20 changed files with 272 additions and 32 deletions.
2 changes: 1 addition & 1 deletion src-tauri/gen/schemas/acl-manifests.json

Large diffs are not rendered by default.

20 changes: 20 additions & 0 deletions src-tauri/gen/schemas/desktop-schema.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 20 additions & 0 deletions src-tauri/gen/schemas/macOS-schema.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src-tauri/yaak-git/bindings/gen_git.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export type GitStatus = "added" | "conflict" | "current" | "modified" | "removed

export type GitStatusEntry = { relaPath: string, status: GitStatus, staged: boolean, prev: SyncModel | null, next: SyncModel | null, };

export type GitStatusSummary = { path: string, headRef: string | null, headRefShorthand: string | null, entries: Array<GitStatusEntry>, origins: Array<string>, branches: Array<string>, };
export type GitStatusSummary = { path: string, headRef: string | null, headRefShorthand: string | null, entries: Array<GitStatusEntry>, origins: Array<string>, localBranches: Array<string>, remoteBranches: Array<string>, };

export type PullResult = { receivedBytes: number, receivedObjects: number, };

Expand Down
1 change: 1 addition & 0 deletions src-tauri/yaak-git/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const COMMANDS: &[&str] = &[
"checkout",
"commit",
"delete_branch",
"fetch_all",
"initialize",
"log",
"merge_branch",
Expand Down
7 changes: 6 additions & 1 deletion src-tauri/yaak-git/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export function useGit(dir: string) {
mutationFn: (args) => invoke('plugin:yaak-git|delete_branch', { dir, ...args }),
onSuccess,
}),
checkout: useMutation<void, string, { branch: string; force: boolean }>({
checkout: useMutation<string, string, { branch: string; force: boolean }>({
mutationKey: ['git', 'checkout', dir],
mutationFn: (args) => invoke('plugin:yaak-git|checkout', { dir, ...args }),
onSuccess,
Expand All @@ -51,6 +51,11 @@ export function useGit(dir: string) {
mutationFn: (args) => invoke('plugin:yaak-git|commit', { dir, ...args }),
onSuccess,
}),
fetchAll: useMutation<string, string, void>({
mutationKey: ['git', 'checkout', dir],
mutationFn: () => invoke('plugin:yaak-git|fetch_all', { dir }),
onSuccess,
}),
push: useMutation<PushResult, string, void>({
mutationKey: ['git', 'push', dir],
mutationFn: () => invoke('plugin:yaak-git|push', { dir }),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Automatically generated - DO NOT EDIT!

"$schema" = "../../schemas/schema.json"

[[permission]]
identifier = "allow-checkout-remote"
description = "Enables the checkout_remote command without any pre-configured scope."
commands.allow = ["checkout_remote"]

[[permission]]
identifier = "deny-checkout-remote"
description = "Denies the checkout_remote command without any pre-configured scope."
commands.deny = ["checkout_remote"]
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Automatically generated - DO NOT EDIT!

"$schema" = "../../schemas/schema.json"

[[permission]]
identifier = "allow-fetch-all"
description = "Enables the fetch_all command without any pre-configured scope."
commands.allow = ["fetch_all"]

[[permission]]
identifier = "deny-fetch-all"
description = "Denies the fetch_all command without any pre-configured scope."
commands.deny = ["fetch_all"]
53 changes: 53 additions & 0 deletions src-tauri/yaak-git/permissions/autogenerated/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Default permissions for the plugin
- `allow-checkout`
- `allow-commit`
- `allow-delete-branch`
- `allow-fetch-all`
- `allow-initialize`
- `allow-log`
- `allow-merge-branch`
Expand Down Expand Up @@ -105,6 +106,32 @@ Denies the checkout command without any pre-configured scope.
<tr>
<td>

`yaak-git:allow-checkout-remote`

</td>
<td>

Enables the checkout_remote command without any pre-configured scope.

</td>
</tr>

<tr>
<td>

`yaak-git:deny-checkout-remote`

</td>
<td>

Denies the checkout_remote command without any pre-configured scope.

</td>
</tr>

<tr>
<td>

`yaak-git:allow-commit`

</td>
Expand Down Expand Up @@ -157,6 +184,32 @@ Denies the delete_branch command without any pre-configured scope.
<tr>
<td>

`yaak-git:allow-fetch-all`

</td>
<td>

Enables the fetch_all command without any pre-configured scope.

</td>
</tr>

<tr>
<td>

`yaak-git:deny-fetch-all`

</td>
<td>

Denies the fetch_all command without any pre-configured scope.

</td>
</tr>

<tr>
<td>

`yaak-git:allow-initialize`

</td>
Expand Down
1 change: 1 addition & 0 deletions src-tauri/yaak-git/permissions/default.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ permissions = [
"allow-checkout",
"allow-commit",
"allow-delete-branch",
"allow-fetch-all",
"allow-initialize",
"allow-log",
"allow-merge-branch",
Expand Down
20 changes: 20 additions & 0 deletions src-tauri/yaak-git/permissions/schemas/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,16 @@
"type": "string",
"const": "deny-checkout"
},
{
"description": "Enables the checkout_remote command without any pre-configured scope.",
"type": "string",
"const": "allow-checkout-remote"
},
{
"description": "Denies the checkout_remote command without any pre-configured scope.",
"type": "string",
"const": "deny-checkout-remote"
},
{
"description": "Enables the commit command without any pre-configured scope.",
"type": "string",
Expand All @@ -344,6 +354,16 @@
"type": "string",
"const": "deny-delete-branch"
},
{
"description": "Enables the fetch_all command without any pre-configured scope.",
"type": "string",
"const": "allow-fetch-all"
},
{
"description": "Denies the fetch_all command without any pre-configured scope.",
"type": "string",
"const": "deny-fetch-all"
},
{
"description": "Enables the initialize command without any pre-configured scope.",
"type": "string",
Expand Down
25 changes: 22 additions & 3 deletions src-tauri/yaak-git/src/branch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,13 @@ pub(crate) fn branch_set_upstream_after_push(repo: &Repository, branch_name: &st
Ok(())
}

pub(crate) fn git_checkout_branch(dir: &Path, branch: &str, force: bool) -> Result<()> {
pub(crate) fn git_checkout_branch(dir: &Path, branch_name: &str, force: bool) -> Result<String> {
if branch_name.starts_with("origin/") {
return git_checkout_remote_branch(dir, branch_name, force);
}

let repo = open_repo(dir)?;
let branch = get_branch_by_name(&repo, branch)?;
let branch = get_branch_by_name(&repo, branch_name)?;
let branch_ref = branch.into_reference();
let branch_tree = branch_ref.peel_to_tree()?;

Expand All @@ -36,7 +40,22 @@ pub(crate) fn git_checkout_branch(dir: &Path, branch: &str, force: bool) -> Resu
repo.checkout_tree(branch_tree.as_object(), Some(&mut options))?;
repo.set_head(branch_ref.name().unwrap())?;

Ok(())
Ok(branch_name.to_string())
}

pub(crate) fn git_checkout_remote_branch(dir: &Path, branch_name: &str, force: bool) -> Result<String> {
let branch_name = branch_name.trim_start_matches("origin/");
let repo = open_repo(dir)?;

let refname = format!("refs/remotes/origin/{}", branch_name);
let remote_ref = repo.find_reference(&refname)?;
let commit = remote_ref.peel_to_commit()?;

let mut new_branch = repo.branch(branch_name, &commit, false)?;
let upstream_name = format!("origin/{}", branch_name);
new_branch.set_upstream(Some(&upstream_name))?;

return git_checkout_branch(dir, branch_name, force)
}

pub(crate) fn git_create_branch(dir: &Path, name: &str) -> Result<()> {
Expand Down
8 changes: 7 additions & 1 deletion src-tauri/yaak-git/src/commands.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::branch::{git_checkout_branch, git_create_branch, git_delete_branch, git_merge_branch};
use crate::error::Result;
use crate::fetch::git_fetch_all;
use crate::git::{
git_add, git_commit, git_init, git_log, git_status, git_unstage, GitCommit, GitStatusSummary,
};
Expand All @@ -10,7 +11,7 @@ use tauri::command;
// NOTE: All of these commands are async to prevent blocking work from locking up the UI

#[command]
pub async fn checkout(dir: &Path, branch: &str, force: bool) -> Result<()> {
pub async fn checkout(dir: &Path, branch: &str, force: bool) -> Result<String> {
git_checkout_branch(dir, branch, force)
}

Expand Down Expand Up @@ -49,6 +50,11 @@ pub async fn commit(dir: &Path, message: &str) -> Result<()> {
git_commit(dir, message)
}

#[command]
pub async fn fetch_all(dir: &Path) -> Result<()> {
git_fetch_all(dir)
}

#[command]
pub async fn push(dir: &Path) -> Result<PushResult> {
git_push(dir)
Expand Down
37 changes: 37 additions & 0 deletions src-tauri/yaak-git/src/fetch.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
use crate::callbacks::default_callbacks;
use crate::error::Result;
use crate::repository::open_repo;
use git2::{FetchOptions, ProxyOptions, Repository};
use std::path::Path;

pub(crate) fn git_fetch_all(dir: &Path) -> Result<()> {
let repo = open_repo(dir)?;
let remotes = repo.remotes()?.iter().flatten().map(String::from).collect::<Vec<_>>();

for (_idx, remote) in remotes.into_iter().enumerate() {
fetch_from_remote(&repo, &remote)?;
}

Ok(())
}

fn fetch_from_remote(repo: &Repository, remote: &str) -> Result<()> {
let mut remote = repo.find_remote(remote)?;

let mut options = FetchOptions::new();
let callbacks = default_callbacks();

options.prune(git2::FetchPrune::On);
let mut proxy = ProxyOptions::new();
proxy.auto();

options.proxy_options(proxy);
options.download_tags(git2::AutotagOption::All);
options.remote_callbacks(callbacks);

remote.fetch(&[] as &[&str], Some(&mut options), None)?;
// fetch tags (also removing remotely deleted ones)
remote.fetch(&["refs/tags/*:refs/tags/*"], Some(&mut options), None)?;

Ok(())
}
Loading

0 comments on commit a42bee0

Please sign in to comment.