Skip to content
Merged
18 changes: 16 additions & 2 deletions ReadMe.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,27 @@ npx git-utility # your arguments here
### Download folders or files from Git repositories

```shell
# Download entire repository
# Download entire repository to current directory
xgit download https://github.com/your-org/your-repo

# Download from specific branch
xgit download https://github.com/your-org/your-repo main

# Download specific folder or file
xgit download https://github.com/your-org/your-repo main path/to/your-folder/or-file

# Download to a specific local path
xgit download https://github.com/your-org/your-repo main path/to/your-folder/or-file ./local-destination
```

### Upload folders to Git repositories

```shell
# Upload a folder to a Git repository on a specific branch (force push)
xgit upload path/to/source-folder https://github.com/your-org/your-repo target-branch

# Upload to a specific directory in the repository (non-force push)
xgit upload path/to/source-folder https://github.com/your-org/your-repo target-branch target/directory
```

### Manage Git submodules
Expand All @@ -46,7 +59,8 @@ xgit submodule remove path/to/submodule

## Commands

- `xgit download <GitURL> [branchName] [folderOrFilePath]` - Download folders or files from a Git repository
- `xgit download <GitURL> [branchName] [folderOrFilePath] [targetFolder]` - Download folders or files from a Git repository
- `xgit upload <sourceFolder> <GitURL> <targetBranch> [targetFolder]` - Upload a folder to a Git repository
- `xgit submodule remove [path]` - Remove a Git submodule

[1]: https://git-scm.com/
Expand Down
9 changes: 5 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "git-utility",
"version": "0.2.1",
"version": "0.3.0",
"license": "LGPL-3.0",
"author": "shiy2008@gmail.com",
"description": "A Git utility CLI tool with some missing sub commands",
Expand All @@ -10,6 +10,7 @@
"command",
"cli",
"download",
"upload",
"submodule"
],
"homepage": "https://github.com/idea2app/Git-utility#readme",
Expand All @@ -25,14 +26,14 @@
"xgit": "dist/index.js"
},
"dependencies": {
"commander-jsx": "^0.7.1",
"commander-jsx": "^0.7.2",
"zx": "^8.8.5"
},
"devDependencies": {
"@types/fs-extra": "^11.0.4",
"@types/node": "^22.18.13",
"@types/node": "^22.19.1",
"husky": "^9.1.7",
"lint-staged": "^16.2.6",
"lint-staged": "^16.2.7",
"prettier": "^3.6.2",
"typescript": "~5.9.3"
},
Expand Down
51 changes: 26 additions & 25 deletions pnpm-lock.yaml

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

74 changes: 64 additions & 10 deletions src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@ $.verbose = true;
async function downloadGitFolder(
GitURL: string,
branchName?: string,
folderOrFilePath?: string
folderOrFilePath?: string,
targetFolder = '.'
) {
const tempFolder = path.join(os.tmpdir(), new URL(GitURL).pathname),
targetFolder = process.cwd();
targetFolder = path.resolve(targetFolder);

const tempFolder = path.join(os.tmpdir(), new URL(GitURL).pathname);

await fs.remove(tempFolder);
await fs.mkdirp(tempFolder);
Expand Down Expand Up @@ -39,10 +41,8 @@ async function downloadGitFolder(
if (sourceStat.isFile()) {
const fileName = path.basename(sourcePath);

await fs.copy(sourcePath, path.join(targetFolder, fileName), {
overwrite: true
});
} else await fs.copy(sourcePath, targetFolder, { overwrite: true });
await fs.copy(sourcePath, path.join(targetFolder, fileName));
} else await fs.copy(sourcePath, targetFolder);
}

async function listSubmodules() {
Expand Down Expand Up @@ -70,25 +70,79 @@ Note: You may want to commit these changes with:
git commit -m "Remove submodule ${submodulePath}"`);
}

async function uploadFolder(
sourceFolder: string,
GitURL: string,
targetBranch: string,
targetFolder?: string
) {
sourceFolder = path.resolve(sourceFolder);

if (targetFolder) {
const tempFolder = path.join(os.tmpdir(), new URL(GitURL).pathname);

await fs.remove(tempFolder);
await fs.mkdirp(tempFolder);
cd(tempFolder);

await $`git clone -b ${targetBranch} ${GitURL} .`;

targetFolder = path.join(tempFolder, targetFolder);

await fs.remove(targetFolder);
await fs.mkdirp(targetFolder);
await fs.copy(sourceFolder, targetFolder);
await fs.remove(path.join(targetFolder, '.git'));

await $`git add .`;
await $`git commit -m "upload by Git-utility CLI"`;
await $`git push origin ${targetBranch}`;
} else {
cd(sourceFolder);

await $`git init`;
await $`git remote add origin ${GitURL}`;
await $`git checkout -b ${targetBranch}`;
await $`git add .`;
await $`git commit -m "upload by Git-utility CLI"`;
await $`git push --set-upstream origin ${targetBranch} -f`;
await fs.remove('.git');
}
}

Command.execute(
<Command name="xgit">
<Command
name="download"
parameters="<GitURL> [branchName] [folderOrFilePath]"
parameters="<GitURL> [branchName] [folderOrFilePath] [targetFolder]"
description="Download folders or files from a Git repository"
executor={(
_,
GitURL: string,
branchName = 'main',
folderOrFilePath?: string
folderOrFilePath?: string,
targetFolder?: string
) =>
downloadGitFolder(
GitURL,
branchName as string,
folderOrFilePath
folderOrFilePath,
targetFolder
)
}
/>
<Command
name="upload"
parameters="<sourceFolder> <GitURL> <targetBranch> [targetFolder]"
description="Upload a folder to a Git repository"
executor={(
_,
sourceFolder: string,
GitURL: string,
targetBranch: string,
targetFolder?: string
) => uploadFolder(sourceFolder, GitURL, targetBranch, targetFolder)}
/>
<Command name="submodule" description="Manage Git submodules">
<Command
name="remove"
Expand Down