An open API service indexing awesome lists of open source software.

https://github.com/rmalik777/git-commander

Git GUI Client
https://github.com/rmalik777/git-commander

git javascript react react-router redux rust shadcn-ui sqlite tailwindcss tauri typescript

Last synced: 3 months ago
JSON representation

Git GUI Client

Awesome Lists containing this project

README

          

# Git Commander

> [!IMPORTANT]
> This program doesn't include git binary. Make sure you have git installed on your system. If you don't have git installed, you can download it from [Git SCM](https://git-scm.com/)

## Download

Available in [release](https://github.com/RMalik777/git-commander/releases)

## Quick Start Dev

### Recommended IDE Setup

- [VS Code](https://code.visualstudio.com/)
- [Tauri](https://marketplace.visualstudio.com/items?itemName=tauri-apps.tauri-vscode)
- [rust-analyzer](https://marketplace.visualstudio.com/items?itemName=rust-lang.rust-analyzer)

### Clone Project

```shell
git clone https://github.com/RMalik777/git-commander.git
cd git-commander
```

### Install Dependencies

pnpm is recommended, if you have `node.js` installed already you can [install npm with corepack](https://pnpm.io/installation#using-corepack). If you don't want to use pnpm, you can continue to use npm.

```shell
npm i
```

### Run Development Build

```shell
npm run tauri dev
```

### Build Production App

```shell
npm run tauri build
```

The finished build will be located inside `./src-tauri/target/release/bundle` in the form of `.msi` inside msi folder and `.exe` inside nsis folder.

More details about building the app can be found in the [Build Section](#build).

## How to use

> UNDER DEVELOPMENT

This guide will provide a basic information on how to use Git Commander.\
If you haven't download the app, you can download the latest version from the [release page](https://github.com/RMalik777/git-commander/releases).

### Initial Setup

Interactive tutorial available inside the application. Access the tutorial by clicking the `Help` button or ![HelpIcon](https://unpkg.com/lucide-static@latest/icons/circle-help.svg) on the left menu bar.

### Functionality

There are a couple things you can do with Git Commander:

#### Quick Access Toolbar

The quick access toolbar is located at the top of the app. It contains the following buttons:

##### Current Repository and Branch

The top centre of the app displays the current repository and branch you are in. If you haven't opened any repository, it will display `No Repository Opened`.

##### Branch ![Branch](https://unpkg.com/lucide-static@latest/icons/git-branch.svg)

To change branch in the repository, click the icon. After that, the popup will appear and you can choose the branch you want to switch to. If there are still unstaged changes, you can't switch branch before committing the changes.

##### Pull ![Pull](https://unpkg.com/lucide-static@latest/icons/arrow-down-to-line.svg)

Pull and integrate changes from the remote repository to the local repository.

##### Push ![Push](https://unpkg.com/lucide-static@latest/icons/arrow-up-from-line.svg)

Push changes from the local repository to the remote repository

##### Undo ![Undo](https://unpkg.com/lucide-static@latest/icons/undo-2.svg)

Undo last commit but keeping the changes made.

> [!NOTE]
> Undoing commit that has been pushed to the remote repository is not recommended. If you want to undo a commit that has been pushed to the remote repository, you should use the `revert` command instead.

#### Open Repository

##### From Local Repo

If you already clone a repository, you can open it by clicking the `Open Repository` button. A dialog will pop up and you can select location where you store your repository.

##### From Remote Repo

If you haven't cloned a repository, you can clone it by clicking the `Clone` button. A dialog will appear, and you can input the repository URL or choose from dropdown (which you can add your own) and the local directory you want to clone the repository to.

##### Close Repo

If you close the repo, it won't delete the repo. The repo will still be stored in the same location you saved it. To delete your repo, you have to delete it manually from the file explorer.

#### Staging

Before you can commit a file, you need to stage (add) it first. To stage the changes you've made, go to staging page and click the plus icon beside the file you want to stage.

#### Commit

To commit changes, enter the commit message in the input field, make sure you follow the commit message format. After that, click the `Commit` button. The changes will be committed to the local repository. After you commit the changes, you can push the changes to the remote repository by clicking the `Push` icon.

## Development

Before you start developing, make sure you develop from the `dev` branch. The `main` branch is the production branch to initiate build automatically. Read more in the [GitHub Actions](#github-actions) section.

```shell
git switch dev
```

### Prerequisite

#### Node.js (and npm)

When you install Node.js, npm will be installed automatically.

1. Download and install the latest version of [Node.js](https://nodejs.org/).
2. Verify your installation by running the following command in your terminal:

```shell
node -v
```

3. Make sure npm is also installed by running the following command in your terminal:

```shell
npm -v
```

#### IDE

> Recommended IDE: [Visual Studio Code](https://code.visualstudio.com/)

Visual Studio Code is preferred, but you can use any text editor you want. If you use Visual Studio Code, the recommended extension will be prompted when you open the project.

#### Dependencies

##### Rust

1. Download latest [Rust](https://www.rust-lang.org/)
2. Follow the installation guide
3. If you use Visual Studio Code, install the [rust-analyzer](https://marketplace.visualstudio.com/items?itemName=rust-lang.rust-analyzer) extension

##### Diesel CLI (optional)

Diesel is used for interacting with database during development. If you're not interacting with database during development, you don't need to install Diesel.

1. Follow Instruction from [Diesel Docs](https://diesel.rs/guides/getting-started)
2. When installing Diesel CLI, only install the SQLite features

```shell
cargo install diesel_cli --no-default-features --features sqlite
```

##### SQLite (optional)

SQLite is used as the database for this project. If you're not manipulating the database with the database during development, you don't need to install SQLite.

1. Download [SQLite](https://www.sqlite.org/download.html)
Choose the download file based on your operating system.

- Download source code\
Example: `sqlite-amalgamation-3450200.zip`
- Download precompiled binaries\
Example: `sqlite-dll-win-x64-3450200.zip`.

2. Extract both file into the same folder
3. Open **Developer Command Prompt for VS 2017/2019/2022** by typing Developer Command in Windows Search (you will need [Visual Studio](https://visualstudio.microsoft.com/vs/)) [^1]
4. Run inside the terminal

```shell
lib /DEF:sqlite3.def /OUT:sqlite3.lib /MACHINE:x64
```

5. If you want to validate the DB structure, edit, and changed data inside the DB by using GUI tools. You can use [DB Browser for SQLite](https://sqlitebrowser.org/dl/)

[^1]:

#### Setting Up

> [!IMPORTANT]
> Make sure you complete the steps in [Dependencies](#dependencies) before continuing.

##### Default Path for the Database

Inside `db.rs`, there will be a `get_db_path` function. If you want to change the directory into the directory you want. For the list of all available directory, check [dirs documentation](https://crates.io/crates/dirs#features). This will be the location for the production database when you build the app.

```rust
// db.rs
fn get_db_path() -> String {
let home_dir = dirs::document_dir().unwrap();
home_dir.to_str().unwrap().to_string() + "/Git-Commander/database.sqlite"
}
```

From the code above, it will create the database file inside your documents folder for example: `C:/Users//Documents/DashOne/database.sqlite`

##### Migration and Database

If you new to Diesel and Rust, follow the tutorial on [Diesel Getting Started Page](https://diesel.rs/guides/getting-started)

1. Rename the `.env.example` file (located inside `/src-tauri`) to `.env`
2. Change the value of `DATABASE_URL` to choose a location for your new database, OR\
Simply run this command in the terminal to create `.env` file and the location simultaneously

```shell
echo DATABASE_URL="PATH FOR YOUR DATABASE" > .env
#Change the value based on the file location
```

To make it easy to maintain, the default value used is in `C:/Users//Documents/Git-Commander/database.sqlite`.

> [!NOTE]
> If you want to change the path, make sure the file path is the same as the one in the `db.rs`. Make sure to change the path in both files.

3. Run the command below to create a database

```shell
diesel setup
```

4. Run Migration

```shell
diesel migration run
```

The command above will run migration based on file inside `/src-tauri/migrations` folder. To undo (revert) the migrations

```shell
diesel migration revert
```

### Front End

Built with [React](https://react.dev/) with UI using [shadcn/ui](https://ui.shadcn.com/). Typescript (`.tsx`) is recommended but not required if you prefer JavaScript(`.jsx`). Styles are built using [Tailwind CSS](https://tailwindcss.com/).\
Please read the related documentation for more information.

#### Pages

To create a new page, put the file inside `/src/routes/pages`. Git Commander used [React Router](https://reactrouter.com/en/main) for routing so add the pages inside the route in `/src/main.jsx`.

#### Components

Components are located inside `/src/components`.

#### shadcn/ui

To use shadcn/ui, go to [shadcn/ui docs](https://ui.shadcn.com/docs/components) and choose the components you want to install. The installed components is located inside `/src/components/ui`

### Git Command

All command related got Git are located inside `/src/lib/git.js`.
Build using Tauri [Tauri Shell API](https://tauri.app/v1/api/js/shell#command). All git commands available can be seen in [Git Documentation](https://git-scm.com/docs)\
List of all command:

| Function Name | Parameter | Git Command | Notes |
| -------------- | --------- | --------------------------------- | ----- |
|`addAll`|`path`|`git add .`|Adding (staging) all changed files.|
|`addFile`|`path`, `file`|`git add `|Adding (staging) specific file.|
|`branchList`|`path`|`git branch -a`|Return a list of all branch .available. Parameter `-a` is used to get all the available branch local and remote.|
|`checkGit`| `path`| `git status`|Checking whether a opened folder is a git repository or not.|
|`clone`|`localRepo`, `remoteRepo`|`git clone `|Clone a remote repository into a local directory.|
|`commit`|`path`, `message`|`git commit -m `|Commit all staged changes.|
|`commitAll`|`path`, `message`|`git add .` + `git commit -m `|Add all changed item and commit it directly.|
| `configUsername` | `path` | `git config user.name ` |Only `path` used as parameter because this function is only setting the user.name on **local** config and **global** config. The username is handled by Redux.|
|`configUsernameReplace` |`path`|`git config --replace-all user.name `|For changing username, if the git require replace all parameter.
**(Unused)**|
|`currentBranch`|`path`|`git branch --show-current`|Get the current branch.|
|`getParent`|`path`|`git rev-parse --show-toplevel`|Get the parent git repository if the current repository is not the parent|
|`pull`|`path`|`git pull`||
|`push`|`path`|`git push`||
|`removeUntrackedFile`|`path`|`git clean -f`|Remove untracked file (new file that hasn't been committed)|
|`removeAll`|`path`|`git restore .`|Revert all changes (including untracked files). This function also call `removeUntrackedFile`|
|`revertFile`|`path`, `file`|`git restore `|Revert all the changes made into the file **(proceed with caution, this action is irreversible)**.|
|`setSSLFalse`|`-`|`git config --global http.sslVerify false`|For disabling SSL Verification.|
|`showChanged`|`path`|`git diff --name-only`|Show all changed file made.|
|`showStaged`|`path`|`git diff --name-only --cached`|Show all staged files.|
|`showUntracked`|`path`|`git ls-files --others --exclude-standard`|Show all untracked files.|
|`switchBranch`|`path`, `branch`|`git switch `|Change branch.|
|`undoLastCommit`|`path`|`git reset --soft HEAD^`|Undo last commit to a last commit known. Option `--soft` to keep all the files untouched. Option `HEAD^` refer to a last commit.|
|`unstageAll`|`path`|`git reset HEAD`|Undo all staged file. No option so the method is default (`--mixed`). HEAD is refering to the current HEAD.|
|`unstageFile`|`path`, `file`|`git restore --staged `|Undo staged but only one specific file.|
|`version`||`git --version`|Check whether git is installed in the target devices. If not the promise will be rejected|

### Database TS Call

Located inside `/src/lib/database.ts`, the function is built using [Tauri Invoke API](https://tauri.app/v1/guides/features/command/). The function will invoke (call) the handler function inside rust file located in `/src-tauri/src/handler`. The Handler then will process the input (if any) and then call the repository function to query the db.\
Types available inside `/src/lib/Types/repo.ts`

| Function Name | Parameter | Return |
| ---------------------- | -------------------- | ----------------------- |
| `checkNameDup` | `repoName` | `Promise` |
| `checkUrlDup` | `repoUrl` | `Promise` |
| `deleteAllRemoteRepo` | `-` | `Promise` |
| `deleteRemoteRepoById` | `id` | `Promise` |
| `getAllRepo` | `-` | `Promise` |
| `getRepoById` | `id` | `Promise` |
| `insertIntoRepo` | `repoName`,`repoUrl` | `Promise` |

### Terminal

Adapted from [tauri-terminal](https://github.com/marc2332/tauri-terminal).\
This use [xterm.js](https://xtermjs.org/) for the terminal. The terminal is located inside `/src/components/Tools/TerminalView.tsx` for the View Components, `/src/lib/terminalFunc.ts` for the Terminal Function. Terminal Function will invoke the handler function inside rust file located in `/src-tauri/src/terminal.rs`.

Before you start development, turn off [React Strict Mode](https://react.dev/reference/react/StrictMode). React Strict Mode will cause the terminal to run twice. To turn off React Strict Mode, go to `/src/index.tsx` and remove the `` tag in `/src/main.tsx`.

```diff
ReactDOM.createRoot(document.getElementById("root")!).render(
-

-
);
```

> [!NOTE]
> Remember to add `` again after you done with the terminal development to continue using Strict Mode.

#### Default Behaviour

##### Windows

The default terminal on Windows is `cmd.exe`. If you want to change the terminal to `powershell` or `bash`, you can change the terminal inside `/src-tauri/src/terminal.rs`.

```rust
#[cfg(target_os = "windows")]
{
cmd = CommandBuilder::new("cmd.exe");
cmd.cwd(directory);
cmd.env("TERM", "cygwin");
}
```

##### Linux and MacOS

> [!IMPORTANT]
> The terminal is only tested in Windows. Linux and MacOS is untested and may not work at all.

The default terminal on Linux and MacOS is `bash`. If you want to change the terminal, you can change it inside `/src-tauri/src/terminal.rs`.

```rust
#[cfg(not(target_os = "windows"))]
{
cmd = CommandBuilder::new("bash");
cmd.env("TERM", "xterm-256color");
}
```

#### Known Issue

- After changing repository, the terminal will not clear the screen.

### Backend (Rust)

### Database

This program use SQLite as the database. When you clone repository, the database is not provided but you can build it.\
On `/src-tauri` folder, there will be a file name `.env.example`. Copy the file and rename it to `.env`. The default path is the same path that reference for the production database (reference inside `/src-tauri/src/db.rs`) which is `C:/Users//Documents/Git-Commander/database.sqlite`. You can change the path to your desired path if you want.

### After Development

#### Formatting

This project use prettier for formatting. Make sure you adhere to the formatting rules inside `.prettierrc.`. To format the code, run the command below:

```shell
npm run format
```

##### Formatting `src-tauri`

The Rust code is formatted using `rustfmt`. To format the code you need to be inside the `src-tauri` folder before running this command:

```shell
# if you not inside the src-tauri folder run the command below, if you already inside the src-tauri, run the cargo fmt directly.
# cd src-tauri
cargo fmt
```

#### Linting

This project use eslint for linting. To adjust the linting rules change `.eslint.config.js`. To lint the code, run the command below:

```shell
npm run lint
```

##### Linting `src-tauri`

The Rust code is linted using `clippy`. To lint the code you need to be inside the `src-tauri` folder before running this command:

```shell
# if you not inside the src-tauri folder run the command below, if you already inside the src-tauri, run the cargo clippy directly.
# cd src-tauri
cargo clippy
```

## Build

To build the app, run the command below:

```shell
npm run tauri build
```

But building the app will only create the app for the current OS. If you want to build for another OS, you have to build it on the OS you want to build for. For example, if you want to build for Windows, you have to run the build command on a Windows Machine. The build may take a long time to finish, depending on your machine. To solve this we can use **GitHub Actions**.

### GitHub Actions

Make sure you develop from the `dev` branch. When you merge a pull request from the `dev` branch to the `main` branch, GitHub Actions will build the app automatically. The workflow file is located inside `.github/workflows/build.yml`. The workflow will build the app for Windows, MacOS, and Linux. The workflow will also manage versioning and bump the version based on [Angular Commits](https://github.com/semantic-release/semantic-release?tab=readme-ov-file#commit-message-format). The build will be uploaded as an artifact and can be downloaded from the GitHub Release page.

## References

### Built With

- [![Git][GitImg]](https://git-scm.com/)
- [![React][ReactImg]](https://react.dev/)
- [![ReactRouter][ReactRouterImg]](https://reactrouter.com/en/main)
- [![Redux][ReduxImg]](https://redux.js.org/)
- [![Rust][RustImg]](https://www.rust-lang.org/)
- [![ShadUi][ShadUiImg]](https://ui.shadcn.com/)
- [![Sqlite][SqliteImg]](https://www.sqlite.org/)
- [![Tailwind][TailwindImg]](https://www.rust-lang.org/)
- [![Tauri][TauriImg]](https://tauri.app/)
- [![Vite][ViteImg]](https://vitejs.dev/)

[GitImg]: https://img.shields.io/badge/GIT-E44C30?style=for-the-badge&logo=git&logoColor=white
[ReactImg]: https://img.shields.io/badge/React-20232A?style=for-the-badge&logo=react&logoColor=61DAFB
[ReactRouterImg]: https://img.shields.io/badge/React_Router-CA4245?style=for-the-badge&logo=react-router&logoColor=white
[ReduxImg]: https://img.shields.io/badge/Redux-593D88?style=for-the-badge&logo=redux&logoColor=white
[RustImg]: https://img.shields.io/badge/Rust-000000?style=for-the-badge&logo=rust&logoColor=white
[ShadUiImg]: https://img.shields.io/badge/shadcn%2Fui-000000?style=for-the-badge&logo=shadcnui&logoColor=white
[SqliteImg]: https://img.shields.io/badge/Sqlite-003B57?style=for-the-badge&logo=sqlite&logoColor=white
[TauriImg]: https://img.shields.io/badge/Tauri-FFC131?style=for-the-badge&logo=Tauri&logoColor=white
[TailwindImg]: https://img.shields.io/badge/Tailwind_CSS-38B2AC?style=for-the-badge&logo=tailwind-css&logoColor=white
[ViteImg]: https://img.shields.io/badge/Vite-B73BFE?style=for-the-badge&logo=vite&logoColor=FFD62E