Skip to content
New issue

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

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

Already on GitHub? # to your account

Add Checkout to Commit #234

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
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
5 changes: 4 additions & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Tauri + Vue + Typescript App</title>
<title>BranchWise</title>
<script>
document.addEventListener('contextmenu', event => event.preventDefault());
</script>
</head>

<body>
Expand Down
25 changes: 25 additions & 0 deletions src-tauri/src/git/git_branch.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
use std::{fs::OpenOptions, io::Write, path::PathBuf};

use serde::{Deserialize, Serialize};

use crate::errors::git_object_error::{CommitError, GitObjectError};

use super::{
git_commit::GitCommit, git_files::GitFilesRequired, git_folders::GIT_FOLDER,
git_project::GitProject, object::GitObject,
};

#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct GitBranch {
Expand All @@ -11,6 +20,22 @@
pub fn new(name: String, commit: String) -> GitBranch {
GitBranch { name, commit }
}

pub fn checkout(&self, project: &GitProject) -> Result<(), GitObjectError> {
GitCommit::from_hash(project, &self.commit)?.checkout(project)?;

Check warning on line 25 in src-tauri/src/git/git_branch.rs

View check run for this annotation

Codecov / codecov/patch

src-tauri/src/git/git_branch.rs#L24-L25

Added lines #L24 - L25 were not covered by tests

let head_path = PathBuf::from(project.get_directory())
.join(GIT_FOLDER)
.join(GitFilesRequired::HEAD.as_ref());
OpenOptions::new()
.write(true)
.open(head_path)
.map_err(|_| GitObjectError::InvalidCommitFile(CommitError::InvalidContent))?
.write_all(self.name.as_bytes())
.map_err(|_| GitObjectError::InvalidHash)?;

Check warning on line 35 in src-tauri/src/git/git_branch.rs

View check run for this annotation

Codecov / codecov/patch

src-tauri/src/git/git_branch.rs#L27-L35

Added lines #L27 - L35 were not covered by tests

Ok(())
}

Check warning on line 38 in src-tauri/src/git/git_branch.rs

View check run for this annotation

Codecov / codecov/patch

src-tauri/src/git/git_branch.rs#L37-L38

Added lines #L37 - L38 were not covered by tests
}

#[cfg(test)]
Expand Down
37 changes: 37 additions & 0 deletions src-tauri/src/git/git_commit.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
use super::{
git_commit_author::{GitCommitAuthor, GitCommitAuthorType},
git_files::GitFilesRequired,
git_folders::GIT_FOLDER,
git_project::GitProject,
git_tree::GitTree,
object::{GitObject, Header},
};
use crate::errors::git_object_error::{CommitError, GitObjectError};
use core::fmt;
use serde::{Deserialize, Serialize};
use std::{fs::OpenOptions, io::Write, path::PathBuf};

pub enum CommitPrefix {
Tree,
Expand Down Expand Up @@ -149,6 +153,39 @@

Ok(history)
}

/**
* Checkout all the files in a commit
*/
pub fn checkout(&self, project: &GitProject) -> Result<(), GitObjectError> {
let files =
GitTree::from_hash(project, self.get_tree_hash())?.get_object_blobs(project, None);

files.iter().for_each(|file| {
let path = PathBuf::from(project.get_directory()).join(&file.0);
let file_in_fs = OpenOptions::new()
.write(true)
.truncate(true)
.create(true)
.open(path);

Check warning on line 170 in src-tauri/src/git/git_commit.rs

View check run for this annotation

Codecov / codecov/patch

src-tauri/src/git/git_commit.rs#L160-L170

Added lines #L160 - L170 were not covered by tests

if let Ok(mut file_in_fs) = file_in_fs {
let _ = file_in_fs.write_all(file.1.data());
}
});

let head_path = PathBuf::from(project.get_directory())
.join(GIT_FOLDER)
.join(GitFilesRequired::HEAD.as_ref());
OpenOptions::new()
.write(true)
.open(head_path)
.map_err(|_| GitObjectError::InvalidCommitFile(CommitError::InvalidContent))?
.write_all(self.get_hash().as_bytes())
.map_err(|_| GitObjectError::InvalidHash)?;

Check warning on line 185 in src-tauri/src/git/git_commit.rs

View check run for this annotation

Codecov / codecov/patch

src-tauri/src/git/git_commit.rs#L172-L185

Added lines #L172 - L185 were not covered by tests

Ok(())
}

Check warning on line 188 in src-tauri/src/git/git_commit.rs

View check run for this annotation

Codecov / codecov/patch

src-tauri/src/git/git_commit.rs#L187-L188

Added lines #L187 - L188 were not covered by tests
}

impl GitObject for GitCommit {
Expand Down
17 changes: 17 additions & 0 deletions src-tauri/src/git/project_folder.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use super::{
git_branch::GitBranch,
git_commit::{GitCommit, GitCommitWithHash},
git_folders::GitBranchType,
git_project::GitProject,
Expand Down Expand Up @@ -83,6 +84,22 @@
.map_err(|_| GitError::InvalidHistory)
}

#[tauri::command]
pub fn checkout_branch(project: GitProject, branch: GitBranch) -> Result<(), GitError> {
branch
.checkout(&project)
.map_err(|_| GitError::NoLocalBranches)
}

Check warning on line 92 in src-tauri/src/git/project_folder.rs

View check run for this annotation

Codecov / codecov/patch

src-tauri/src/git/project_folder.rs#L88-L92

Added lines #L88 - L92 were not covered by tests

#[tauri::command]
pub fn checkout_commit(project: GitProject, hash: &str) -> Result<(), GitError> {
let commit = GitCommit::from_hash(&project, hash).map_err(|_| GitError::InvalidHistory)?;

Check warning on line 96 in src-tauri/src/git/project_folder.rs

View check run for this annotation

Codecov / codecov/patch

src-tauri/src/git/project_folder.rs#L95-L96

Added lines #L95 - L96 were not covered by tests

commit
.checkout(&project)
.map_err(|_| GitError::InvalidHistory)
}

Check warning on line 101 in src-tauri/src/git/project_folder.rs

View check run for this annotation

Codecov / codecov/patch

src-tauri/src/git/project_folder.rs#L98-L101

Added lines #L98 - L101 were not covered by tests

#[cfg(test)]
mod tests {
use std::{
Expand Down
4 changes: 3 additions & 1 deletion src-tauri/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use database::storage::DATABASE;
use errors::git_error::GitErrorProject;
use git::project_folder::{
get_commit_history, get_database_projects, open_git_project, remove_database_project,
set_current_project,
set_current_project, checkout_branch, checkout_commit
};
use tauri::{AppHandle, Emitter, Manager};

Expand Down Expand Up @@ -89,6 +89,8 @@ fn main() {
remove_database_project,
set_current_project,
get_commit_history,
checkout_branch,
checkout_commit
])
.run(tauri::generate_context!())
.expect("error while running tauri application");
Expand Down
13 changes: 8 additions & 5 deletions src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,13 @@
{{ snackbar.text }}
</v-snackbar>
<DialogComponent />
<ContextMenu />
</v-app>
</template>

<script lang="ts">
import DialogComponent from "@/components/DialogComponent.vue";
import ContextMenu from "@/components/Dialogs/ContextMenu.vue";
import SidebarComponent from "@/components/SidebarComponent.vue";
import TopbarComponent from "@/components/TopbarComponent.vue";
import { registerListeners, unregisterListeners } from "@/listeners";
Expand All @@ -35,7 +37,8 @@ export default defineComponent({
components: {
SidebarComponent,
TopbarComponent,
DialogComponent
DialogComponent,
ContextMenu
},
data() {
return {
Expand Down Expand Up @@ -63,14 +66,14 @@ export default defineComponent({

<style>
html {
overflow: scroll;
overflow-x: hidden;
overflow: scroll;
overflow-x: hidden;
overflow-y: hidden;
}

::-webkit-scrollbar {
width: 0;
background: transparent;
width: 0;
background: transparent;
display: none;
}
</style>
58 changes: 58 additions & 0 deletions src/components/Dialogs/ContextMenu.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<template>
<v-menu
:model-value="isShowing"
:target="[posX, posY]"
@update:model-value="closeMenu"
>
<v-list>
<v-list-item>
<v-list-item-title @click="checkout">
Checkout
</v-list-item-title>
</v-list-item>
</v-list>
</v-menu>
</template>

<script lang="ts">
import { useDialogStore } from "@/stores/dialogs";
import { useProjectStore } from "@/stores/project";
import { TauriCommands } from "@/types/tauri";
import { invoke } from "@tauri-apps/api/core";
import { mapState } from "pinia";
import { defineComponent } from "vue";

export default defineComponent({
name: "ContextMenu",
computed: {
isShowing: {
get() {
return this.contextMenu.isOpen;
},
set(value: boolean) {
if (value === false) {
useDialogStore().closeContextMenu();
}
}
},
posX() {
return useDialogStore().contextMenu.position.x;
},
posY() {
return useDialogStore().contextMenu.position.y;
},
...mapState(useDialogStore, ["contextMenu"])
},
methods: {
closeMenu() {
useDialogStore().closeContextMenu();
},
checkout() {
invoke(TauriCommands.CheckoutCommit, {
project: useProjectStore().getSelectedProject,
hash: useDialogStore().contextMenu.commitHash
});
}
}
});
</script>
21 changes: 13 additions & 8 deletions src/components/Project/Commit/CommitListItem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
style="height: 10vh;"
:class="commitClass"
@click="setCommit"
@click.right="showContextMenu"
>
<v-col
style="height: 85%;"
Expand Down Expand Up @@ -42,14 +43,15 @@
{{ getHash }}
</p>
<v-spacer />

{{ getMessage }}
</v-row>
</v-col>
</v-row>
</template>

<script lang="ts">
import { useDialogStore } from "@/stores/dialogs";
import { useProjectStore } from "@/stores/project";
import { getAuthorDate } from "@/types/gitAuthor";
import { getHash, IGitCommit } from "@/types/gitCommit";
Expand Down Expand Up @@ -93,26 +95,29 @@ export default defineComponent({
methods: {
setCommit() {
useProjectStore().setCommit(this.commit.hash);
},
showContextMenu(event: MouseEvent) {
useDialogStore().showContextMenu(getHash(this.commit), event.clientX, event.clientY);
}
}
});
</script>

<style scoped>
.hoverable:hover {
background-color: black;
cursor: pointer;
border-radius: 25px;
background-color: black;
cursor: pointer;
border-radius: 25px;
}

.selected {
background-color: #112233;
border-radius: 25px;
background-color: #112233;
border-radius: 25px;
}

.selected:hover {
background-color: #112233;
cursor: default !important;
background-color: #112233;
cursor: default !important;
}

</style>
31 changes: 30 additions & 1 deletion src/stores/dialogs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,15 @@ interface IDialogState {
title: string;
message: string;
onConfirm: () => void;
}
},
contextMenu: {
isOpen: boolean;
commitHash: string;
position: {
x: number;
y: number;
};
}
}

export const useDialogStore = defineStore("dialog", {
Expand All @@ -30,6 +38,14 @@ export const useDialogStore = defineStore("dialog", {
title: "",
message: "",
onConfirm: () => { return; }
},
contextMenu: {
isOpen: false,
commitHash: "",
position: {
x: 0,
y: 0
}
}
}),
actions: {
Expand Down Expand Up @@ -57,6 +73,19 @@ export const useDialogStore = defineStore("dialog", {
},
closeConfirmationDialog() {
this.confirmationDialog.isOpen = false;
},
showContextMenu(hash: string, x: number, y: number) {
this.contextMenu = {
position: {
x,
y
},
commitHash: hash,
isOpen: true
};
},
closeContextMenu() {
this.contextMenu.isOpen = false;
}
}
});
2 changes: 2 additions & 0 deletions src/types/tauri.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ export enum TauriCommands {
RemoveDatabaseProject = "remove_database_project",
SetCurrentBranch = "set_current_branch",
SetCurrentProject = "set_current_project",
CheckoutBranch = "checkout_branch",
CheckoutCommit = "checkout_commit",
}

export enum TauriListen {
Expand Down
Loading