gitpick 0.0.0-624db16f060309
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +158 -0
- package/dist/index.js +34 -0
- package/package.json +67 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Neeraj Dalal
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
# GitPick
|
|
2
|
+
|
|
3
|
+
With [gitpick](https://www.npmjs.com/package/gitpick), you can clone precisely what you need.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/gitpick)
|
|
6
|
+
[](https://www.npmjs.com/package/gitpick)
|
|
7
|
+
[](https://github.com/nrjdalal/gitpick)
|
|
8
|
+
|
|
9
|
+
Tired of cloning an entire repository when you only need a specific file or folder? Need to watch remote changes and sync them locally? GitPick is here to help!
|
|
10
|
+
|
|
11
|
+
Simply copy the Github URL and run with `npx gitpick <url>`, be that a public or a private repository.
|
|
12
|
+
|
|
13
|
+
- Target is optional, and `gitpick` follows default git clone behavior. Read [usage](#usage) for more details.
|
|
14
|
+
|
|
15
|
+
<img width="400" alt="GitPick Meme" src="https://github.com/user-attachments/assets/dde09ae9-1ee4-4cd8-a181-91f8e6ed6ba6" />
|
|
16
|
+
|
|
17
|
+
## Features
|
|
18
|
+
|
|
19
|
+
Shorthand (or use full URL):
|
|
20
|
+
|
|
21
|
+
```sh
|
|
22
|
+
npx gitpick TanStack/router
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Or clone a repository:
|
|
26
|
+
|
|
27
|
+
```sh
|
|
28
|
+
npx gitpick https://github.com/TanStack/router
|
|
29
|
+
# npx gitpick TanStack/router
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Or clone a specific directory:
|
|
33
|
+
|
|
34
|
+
```sh
|
|
35
|
+
npx gitpick https://github.com/TanStack/router/tree/main/examples
|
|
36
|
+
# npx gitpick TanStack/router/tree/main/examples
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Or clone a specific file:
|
|
40
|
+
|
|
41
|
+
```sh
|
|
42
|
+
npx gitpick https://github.com/TanStack/router/tree/main/package.json
|
|
43
|
+
# npx gitpick TanStack/router/tree/main/package.json
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
- Clone a file or directory from a GitHub repository.
|
|
47
|
+
- Autodetect branch and target directory if not provided explicitly.
|
|
48
|
+
- Clone from public or private repositories using personal access tokens.
|
|
49
|
+
- Overwrite existing files without prompt using `-o` or `--overwrite` flag.
|
|
50
|
+
- Sync changes with remote repository at a specified interval using `-w` or `--watch` flag.
|
|
51
|
+
- Use shorthands like `npx gitpick TanStack/router` or `npx gitpick TanStack/router/tree/main/examples`, no need to provide full URL.
|
|
52
|
+
|
|
53
|
+
<img width="600" alt="Demo Image" src="https://github.com/user-attachments/assets/954f670a-f30d-43cf-b674-f65a170c989d" />
|
|
54
|
+
|
|
55
|
+
## Usage
|
|
56
|
+
|
|
57
|
+
```text
|
|
58
|
+
With gitpick, you can clone precisely what you need.
|
|
59
|
+
|
|
60
|
+
🚀 More awesome tools at https://github.com/nrjdalal
|
|
61
|
+
|
|
62
|
+
-------------------------------------
|
|
63
|
+
gitpick <url> [target] [options]
|
|
64
|
+
-------------------------------------
|
|
65
|
+
|
|
66
|
+
Hint: Target is optional, and follows default git clone behavior.
|
|
67
|
+
|
|
68
|
+
Arguments:
|
|
69
|
+
url GitHub URL with path to file/folder
|
|
70
|
+
target Directory to clone into (optional)
|
|
71
|
+
|
|
72
|
+
Options:
|
|
73
|
+
-b, --branch Branch to clone
|
|
74
|
+
-o, --overwrite Skip overwrite prompt
|
|
75
|
+
-w, --watch [time] Watch the repository and sync every [time]
|
|
76
|
+
(e.g. 1h, 30m, 15s) default: 1m
|
|
77
|
+
-h, --help display help for command
|
|
78
|
+
-v, --version display the version number
|
|
79
|
+
|
|
80
|
+
Examples:
|
|
81
|
+
$ gitpick <url>
|
|
82
|
+
$ gitpick <url> [target]
|
|
83
|
+
$ gitpick <url> [target] -b [branch]
|
|
84
|
+
$ gitpick <url> [target] -w [time]
|
|
85
|
+
$ gitpick <url> [target] -b [branch] -w [time]
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
If you wish to clone a private repository, generate a [personal access token](https://github.com/settings/personal-access-tokens/new).
|
|
89
|
+
|
|
90
|
+
- For fine-grained access, select Repository permissions to be `Contents: Read-Only`.
|
|
91
|
+
|
|
92
|
+
- Use `https://<token>@github.com` as URL prefix when cloning.
|
|
93
|
+
|
|
94
|
+
Checkout https://github.com/nrjdalal for more awesome repositories.
|
|
95
|
+
|
|
96
|
+
## Installation
|
|
97
|
+
|
|
98
|
+
You can install GitPick globally using npm:
|
|
99
|
+
|
|
100
|
+
```sh
|
|
101
|
+
npm install -g gitpick
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
After installing, you can run the command:
|
|
105
|
+
|
|
106
|
+
```sh
|
|
107
|
+
gitpick <url> [target] [options]
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Or use `npx` to run the command without installing:
|
|
111
|
+
|
|
112
|
+
```sh
|
|
113
|
+
npx gitpick <url> [target] [options]
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## Usage
|
|
117
|
+
|
|
118
|
+
Run `npx gitpick <url> [target] [options]` to clone a file or directory from a GitHub repository.
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
Say your files are located at following GitHub URL with a directory:
|
|
123
|
+
|
|
124
|
+
> https://github.com/nrjdalal/nrjdalal/tree/main/.config
|
|
125
|
+
|
|
126
|
+
You can sync them to a target directory in your project using:
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
npx gitpick https://github.com/nrjdalal/nrjdalal/tree/main/.config config
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
> This will clone the `.config` directory from the `nrjdalal/nrjdalal` repository to the `config` directory in your project. If no target directory is given, it will use the last segment of the URL, e.g., in this case, `.config`.
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
If you need to watch for changes, just add `-w` or `-w [time]` (e.g., `1s`, `1m`, `1h` which is time in a human-readable format, default is `1m`):
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
gitpick https://github.com/nrjdalal/nrjdalal/tree/main/.config -w
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
Additionally, you can use this tool to clone any file or directory from any repository. For example:
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
gitpick https://github.com/nrjdalal/awesome-templates/tree/main/next.js-apps/next.js-pro
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
The above command will clone the `next.js-pro` template from that particular repository.
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
I would love feedback from you all. Let's go!
|
|
155
|
+
|
|
156
|
+
## License
|
|
157
|
+
|
|
158
|
+
This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import l from"fs";import S from"os";import u from"path";function w(e){if(typeof e=="number"||/^\d+$/.test(e))return typeof e=="number"?e:parseInt(e,10);let n=/(\d+)([hms])/g,t=0,r;for(;(r=n.exec(e))!==null;){let o=parseInt(r[1],10);switch(r[2]){case"h":t+=o*36e5;break;case"m":t+=o*6e4;break;case"s":t+=o*1e3;break}}return t}import C from"simple-git";var v=async e=>{var o,i;let n=await C().listRemote([e]),t=(o=n.match(/(.+)\s+HEAD/))==null?void 0:o[1],r=(i=n.match(new RegExp(`${t}\\s+refs/heads/(.+)`)))==null?void 0:i[1];if(!r)throw new Error("Could not determine default branch!");return r};async function $(e,{branch:n,target:t}){let r=/^https:\/\/([^@]+)@github\.com/,o=e.match(r),i="";o&&(i=o[1],e=e.replace(r,"https://github.com"));let m=["git@github.com:","https://github.com/","https://raw.githubusercontent.com/"];for(let y of m)if(e.startsWith(y)){e=e.replace(y,"");break}let a=e.split("/"),h=a[0],f=a[1].endsWith(".git")?a[1].slice(0,-4):a[1],g=a[2]==="blob"?"blob":a[2]==="tree"?"tree":a[2]+a[3]==="refsheads"?"raw":"repository",D=n||(g==="repository"?await v(`https://${i&&i+"@"}github.com/${h}/${f}`):g==="raw"?a[4]:a[3]),b=g?g==="raw"?a.slice(5).join("/"):a.slice(4).join("/"):a.slice(2).join("/")||"/",T=t||(g==="blob"?".":b.split("/").pop()||f);return{token:i,owner:h,repository:f,type:g,branch:D,path:b,target:T}}import{cancel as G,confirm as H,intro as I,isCancel as W,log as p,spinner as A}from"@clack/prompts";import{Command as U}from"commander";import F from"simple-git";import d from"yoctocolors";import{z as c}from"zod";import{fromError as L}from"zod-validation-error";var R=c.object({url:c.string(),target:c.string().optional(),branch:c.string().optional(),overwrite:c.boolean().optional(),force:c.boolean().optional(),watch:c.union([c.string(),c.number(),c.boolean()]).optional()}),x=new U().name("clone").argument("<url>","GitHub URL with path to file/folder").argument("[target]","Directory to clone into (optional)").option("-b, --branch <branch>","Branch to clone").option("-o, --overwrite","Skip overwrite prompt").option("-f, --force","Alias for --overwrite").option("-w, --watch [time]",`Watch the repository and sync every [time]
|
|
3
|
+
(e.g. 1h, 30m, 15s) default: 1m`).action(async(e,n,t)=>{R.parse({url:e,target:n,branch:t.branch,overwrite:t.overwrite,force:t.force,watch:t.watch}),t.overwrite=t.overwrite||t.force,t.watch&&(typeof t.watch=="boolean"&&(t.watch="1m"),console.log(`\u{1F440} Watching every ${w(t.watch)/1e3+"s"}
|
|
4
|
+
`));let r=await $(e,{branch:t.branch,target:n});I(`${d.bold(r.owner)}/${d.bold(r.repository)} ${d.green(`<${r.type}:${r.branch}>`)} ${r.type==="repository"?`> ${d.cyan(r.target)}`:`${d.yellow(r.path)} > ${d.cyan(`${r.target}${r.type==="blob"?`/${r.path.split("/").pop()}`:""}`)}`}`);try{let o=u.resolve(r.target);if(t.watch&&(t.overwrite=!0),l.existsSync(o+(r.type==="blob"?"/"+r.path.split("/").pop():""))&&(await l.promises.readdir(o)).length&&!t.overwrite){let i=r.type==="tree"?"The target directory is not empty. Do you want to overwrite the files?":"The target file already exists. Do you want to overwrite the file?",m=await H({message:i});W(m)&&(G("Operation cancelled."),process.exit(0)),m||(p.info("Chose not to overwrite files."),process.exit(0)),p.info("You can use -o | --overwrite or -f | --force flag to skip this prompt next time.")}if(await k(r,t,o),t.watch){let i=w(t.watch);setInterval(async()=>await k(r,t,o),i)}}catch(o){if(p.error("Level 1: An error occurred"),o instanceof c.ZodError){let i=L(o);p.error("Validation Error: "+i.toString())}else o instanceof Error?p.error("Error: "+o.message):p.error("Unexpected Error: "+JSON.stringify(o,null,2));process.exit(1)}});async function j(e,n){let t=await l.promises.readdir(e,{withFileTypes:!0});await l.promises.mkdir(n,{recursive:!0});for(let r of t){if(r.name===".git")continue;let o=u.join(e,r.name),i=u.join(n,r.name);r.isDirectory()?await j(o,i):await l.promises.copyFile(o,i)}}var k=async(e,n,t)=>{let r=A();try{let o=F();process.platform==="win32"&&await o.raw(["config","--global","core.longpaths","true"]);let i=`https://${e.token?e.token+"@":e.token}github.com/${e.owner}/${e.repository}.git`,m=u.join(S.tmpdir(),`${e.repository}-${Date.now()}${Math.random().toString(16).slice(2,6)}`);n.watch||r.start(`Picking ${e.type}${e.type==="repository"?" without .git":" from repository"}`);let a=performance.now();await o.clone(i,m,["--depth","1","--single-branch","--branch",e.branch]);let h=u.join(m,e.path);(await l.promises.stat(h)).isDirectory()?(await l.promises.mkdir(t,{recursive:!0}),await j(h,t)):(await l.promises.mkdir(t,{recursive:!0}),await l.promises.copyFile(h,t+"/"+e.path.split("/").pop())),n.watch?p.success("Synced at "+new Date().toLocaleTimeString()):r.stop(`Picked ${e.type}${e.type==="repository"?" without .git":" from repository"} in ${((performance.now()-a)/1e3).toFixed(2)} seconds!`),await l.promises.rm(m,{recursive:!0,force:!0})}catch(o){r.stop("Level 2: An error occurred while cloning!"),o instanceof Error?p.error("Error: "+o.message):p.error("Unexpected Error: "+JSON.stringify(o,null,2)),process.exit(1)}};import{Command as M}from"commander";import z from"terminal-link";import s from"yoctocolors";var E={name:"gitpick",version:"3.26.0",description:"With gitpick, you can clone precisely what you need.",keywords:["clone","degit","directory","file","folder","git","github","scaffolding","template","url"],homepage:"https://github.com/nrjdalal/gitpick#readme",bugs:"https://github.com/nrjdalal/gitpick/issues",repository:"nrjdalal/gitpick",funding:"https://github.com/sponsors/nrjdalal",license:"MIT",author:{name:"Neeraj Dalal",email:"admin@nrjdalal.com",url:"https://nrjdalal.com"},type:"module",bin:{degit:"./dist/index.js",gitpick:"./dist/index.js"},files:["dist"],scripts:{build:"tsup",dev:"tsup --watch",prepare:"npx simple-git-hooks",test:"bun run build && node dist/index.js",tests:"bash tests.sh"},"simple-git-hooks":{"pre-commit":"npx lint-staged","commit-msg":"npx commitlint --edit $1"},dependencies:{"@clack/prompts":"^0.10.0",commander:"^13.1.0","simple-git":"^3.27.0","terminal-link":"^4.0.0",yoctocolors:"^2.1.1",zod:"^3.24.2","zod-validation-error":"^3.4.0"},devDependencies:{"@commitlint/cli":"^19.8.0","@commitlint/config-conventional":"^19.8.0","@ianvs/prettier-plugin-sort-imports":"^4.4.1","@types/node":"^22.13.13","lint-staged":"^15.5.0",prettier:"^3.5.3","simple-git-hooks":"^2.12.1","sort-package-json":"^2.15.1",tsup:"^8.4.0",typescript:"^5.8.2"}};process.on("SIGINT",()=>process.exit(0));process.on("SIGTERM",()=>process.exit(0));async function N(){let e=new M().name("gitpick").description("With gitpick, you can clone precisely what you need.").version(E.version||"1.0.0","-v, --version","display the version number"),n=process.argv.slice(2),t=["-v","--version","-h","--help","help","clone"];n.length&&!t.includes(n[0])&&process.argv.splice(2,0,"clone"),e.addCommand(x),e.configureHelp({formatHelp:()=>`${s.bold("With gitpick, you can clone precisely what you need.")}
|
|
5
|
+
|
|
6
|
+
\u{1F680} More awesome tools at ${s.cyan("https://github.com/nrjdalal")}
|
|
7
|
+
|
|
8
|
+
-------------------------------------
|
|
9
|
+
${s.cyan("gitpick <url>")} ${s.green("[target]")} ${s.blue("[options]")}
|
|
10
|
+
-------------------------------------
|
|
11
|
+
|
|
12
|
+
${s.bold("Hint:")} Target is optional, and follows default git clone behavior.
|
|
13
|
+
|
|
14
|
+
${s.bold("Arguments:")}
|
|
15
|
+
${s.cyan("url")} GitHub URL with path to file/folder
|
|
16
|
+
${s.green("target")} Directory to clone into (optional)
|
|
17
|
+
|
|
18
|
+
${s.bold("Options:")}
|
|
19
|
+
${s.blue("-b, --branch ")} Branch to clone
|
|
20
|
+
${s.blue("-o, --overwrite")} Skip overwrite prompt
|
|
21
|
+
${s.blue("-w, --watch [time]")} Watch the repository and sync every [time]
|
|
22
|
+
(e.g. 1h, 30m, 15s) default: 1m
|
|
23
|
+
${s.blue("-h, --help")} display help for command
|
|
24
|
+
${s.blue("-v, --version")} display the version number
|
|
25
|
+
|
|
26
|
+
${s.bold("Examples:")}
|
|
27
|
+
$ gitpick <url>
|
|
28
|
+
$ gitpick <url> [target]
|
|
29
|
+
$ gitpick <url> [target] -b [branch]
|
|
30
|
+
$ gitpick <url> [target] -w [time]
|
|
31
|
+
$ gitpick <url> [target] -b [branch] -w [time]
|
|
32
|
+
`}),console.log(s.dim(`
|
|
33
|
+
${z("GitPick \u2197\uFE0F ","https://github.com/nrjdalal/gitpick")} - Clone specific directories or files from GitHub!
|
|
34
|
+
`)),e.parse()}N();
|
package/package.json
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "gitpick",
|
|
3
|
+
"version": "0.0.0-624db16f060309",
|
|
4
|
+
"description": "With gitpick, you can clone precisely what you need.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"clone",
|
|
7
|
+
"degit",
|
|
8
|
+
"directory",
|
|
9
|
+
"file",
|
|
10
|
+
"folder",
|
|
11
|
+
"git",
|
|
12
|
+
"github",
|
|
13
|
+
"scaffolding",
|
|
14
|
+
"template",
|
|
15
|
+
"url"
|
|
16
|
+
],
|
|
17
|
+
"homepage": "https://github.com/nrjdalal/gitpick#readme",
|
|
18
|
+
"bugs": "https://github.com/nrjdalal/gitpick/issues",
|
|
19
|
+
"repository": "nrjdalal/gitpick",
|
|
20
|
+
"funding": "https://github.com/sponsors/nrjdalal",
|
|
21
|
+
"license": "MIT",
|
|
22
|
+
"author": {
|
|
23
|
+
"name": "Neeraj Dalal",
|
|
24
|
+
"email": "admin@nrjdalal.com",
|
|
25
|
+
"url": "https://nrjdalal.com"
|
|
26
|
+
},
|
|
27
|
+
"type": "module",
|
|
28
|
+
"bin": {
|
|
29
|
+
"degit": "./dist/index.js",
|
|
30
|
+
"gitpick": "./dist/index.js"
|
|
31
|
+
},
|
|
32
|
+
"files": [
|
|
33
|
+
"dist"
|
|
34
|
+
],
|
|
35
|
+
"scripts": {
|
|
36
|
+
"build": "tsup",
|
|
37
|
+
"dev": "tsup --watch",
|
|
38
|
+
"prepare": "npx simple-git-hooks",
|
|
39
|
+
"test": "bun run build && node dist/index.js",
|
|
40
|
+
"tests": "bash tests.sh"
|
|
41
|
+
},
|
|
42
|
+
"simple-git-hooks": {
|
|
43
|
+
"pre-commit": "npx lint-staged",
|
|
44
|
+
"commit-msg": "npx commitlint --edit $1"
|
|
45
|
+
},
|
|
46
|
+
"dependencies": {
|
|
47
|
+
"@clack/prompts": "^0.10.0",
|
|
48
|
+
"commander": "^13.1.0",
|
|
49
|
+
"simple-git": "^3.27.0",
|
|
50
|
+
"terminal-link": "^4.0.0",
|
|
51
|
+
"yoctocolors": "^2.1.1",
|
|
52
|
+
"zod": "^3.24.2",
|
|
53
|
+
"zod-validation-error": "^3.4.0"
|
|
54
|
+
},
|
|
55
|
+
"devDependencies": {
|
|
56
|
+
"@commitlint/cli": "^19.8.0",
|
|
57
|
+
"@commitlint/config-conventional": "^19.8.0",
|
|
58
|
+
"@ianvs/prettier-plugin-sort-imports": "^4.4.1",
|
|
59
|
+
"@types/node": "^22.13.13",
|
|
60
|
+
"lint-staged": "^15.5.0",
|
|
61
|
+
"prettier": "^3.5.3",
|
|
62
|
+
"simple-git-hooks": "^2.12.1",
|
|
63
|
+
"sort-package-json": "^2.15.1",
|
|
64
|
+
"tsup": "^8.4.0",
|
|
65
|
+
"typescript": "^5.8.2"
|
|
66
|
+
}
|
|
67
|
+
}
|