Compare commits
48 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 5f878793fd | |||
| fd6400ed68 | |||
| faf68e2052 | |||
| 7296795aec | |||
| 88252fffc8 | |||
| e67f5a7db4 | |||
| 87e0247b48 | |||
| d490d3ab84 | |||
| f7870797ac | |||
| 17ffc793e0 | |||
| d3738f0887 | |||
| 7da879d483 | |||
| c0bb71f84f | |||
| 230f380a6a | |||
| 852f445b1f | |||
| 584f68ba42 | |||
| 92092ed4af | |||
| fadf687a3e | |||
| 3a18870537 | |||
| cf80678ccc | |||
| 08ce4b6add | |||
| 39075a6269 | |||
| 906ead80a4 | |||
| 7038661296 | |||
| 543bf94a51 | |||
| 453f73c2a0 | |||
| 7e673200c8 | |||
| 44a716248e | |||
| d20006a325 | |||
| f8adec1413 | |||
| 868269359c | |||
| 61d4a4a0d8 | |||
| 4e4de95a07 | |||
| 9b64de7991 | |||
| e45de3b498 | |||
| 6e4c388195 | |||
| 6436a8194e | |||
| f10ae25b2a | |||
| fd6b3b7438 | |||
| d68ff012f2 | |||
| 9aad65edac | |||
| c370ef5815 | |||
| 8f5b743ea4 | |||
| c0e981dbd4 | |||
| 4303621b30 | |||
| 63e04a9dcf | |||
| 08ee946f2e | |||
| 81de5a2d70 |
316
Cargo.lock
generated
316
Cargo.lock
generated
@@ -24,9 +24,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "autocfg"
|
name = "autocfg"
|
||||||
version = "1.0.1"
|
version = "1.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
|
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "bitflags"
|
||||||
@@ -36,9 +36,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.0.72"
|
version = "1.0.73"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee"
|
checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"jobserver",
|
"jobserver",
|
||||||
]
|
]
|
||||||
@@ -51,16 +51,16 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap"
|
name = "clap"
|
||||||
version = "3.0.5"
|
version = "3.1.17"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f6f34b09b9ee8c7c7b400fe2f8df39cafc9538b03d6ba7f4ae13e4cb90bfbb7d"
|
checksum = "47582c09be7c8b32c0ab3a6181825ababb713fde6fff20fc573a3870dd45c6a0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"atty",
|
"atty",
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"clap_derive",
|
"clap_derive",
|
||||||
|
"clap_lex",
|
||||||
"indexmap",
|
"indexmap",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"os_str_bytes",
|
|
||||||
"strsim",
|
"strsim",
|
||||||
"termcolor",
|
"termcolor",
|
||||||
"textwrap",
|
"textwrap",
|
||||||
@@ -68,9 +68,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap_derive"
|
name = "clap_derive"
|
||||||
version = "3.0.5"
|
version = "3.1.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "41a0645a430ec9136d2d701e54a95d557de12649a9dd7109ced3187e648ac824"
|
checksum = "a3aab4734e083b809aaf5794e14e756d1c798d2c69c7f7de7a09a2f5214993c1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"heck 0.4.0",
|
"heck 0.4.0",
|
||||||
"proc-macro-error",
|
"proc-macro-error",
|
||||||
@@ -80,10 +80,19 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "comfy-table"
|
name = "clap_lex"
|
||||||
version = "5.0.0"
|
version = "0.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c42350b81f044f576ff88ac750419f914abb46a03831bb1747134344ee7a4e64"
|
checksum = "a37c35f1112dad5e6e0b1adaff798507497a18fceeb30cceb3bae7d1427b9213"
|
||||||
|
dependencies = [
|
||||||
|
"os_str_bytes",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "comfy-table"
|
||||||
|
version = "5.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b103d85ca6e209388771bfb7aa6b68a7aeec4afbf6f0a0264bfbf50360e5212e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"crossterm",
|
"crossterm",
|
||||||
"strum",
|
"strum",
|
||||||
@@ -108,9 +117,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crossterm"
|
name = "crossterm"
|
||||||
version = "0.22.1"
|
version = "0.23.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c85525306c4291d1b73ce93c8acf9c339f9b213aef6c1d85c3830cbf1c16325c"
|
checksum = "a2102ea4f781910f8a5b98dd061f4c2023f479ce7bb1236330099ceb5a93cf17"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"crossterm_winapi",
|
"crossterm_winapi",
|
||||||
@@ -176,18 +185,18 @@ checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "getrandom"
|
name = "getrandom"
|
||||||
version = "0.2.3"
|
version = "0.2.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753"
|
checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"libc",
|
"libc",
|
||||||
"wasi",
|
"wasi 0.10.2+wasi-snapshot-preview1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "git-repo-manager"
|
name = "git-repo-manager"
|
||||||
version = "0.5.0"
|
version = "0.6.2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap",
|
"clap",
|
||||||
"comfy-table",
|
"comfy-table",
|
||||||
@@ -195,6 +204,7 @@ dependencies = [
|
|||||||
"git2",
|
"git2",
|
||||||
"regex",
|
"regex",
|
||||||
"serde",
|
"serde",
|
||||||
|
"serde_yaml",
|
||||||
"shellexpand",
|
"shellexpand",
|
||||||
"tempdir",
|
"tempdir",
|
||||||
"toml",
|
"toml",
|
||||||
@@ -202,9 +212,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "git2"
|
name = "git2"
|
||||||
version = "0.13.25"
|
version = "0.14.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f29229cc1b24c0e6062f6e742aa3e256492a5323365e5ed3413599f8a5eff7d6"
|
checksum = "5e77a14ffc6ba4ad5188d6cf428894c4fcfda725326b37558f35bb677e712cec"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"libc",
|
"libc",
|
||||||
@@ -258,23 +268,14 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "indexmap"
|
name = "indexmap"
|
||||||
version = "1.8.0"
|
version = "1.8.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "282a6247722caba404c065016bbfa522806e51714c34f5dfc3e4a3a46fcb4223"
|
checksum = "0f647032dfaa1f8b6dc29bd3edb7bbef4861b8b8007ebb118d6db284fd59f6ee"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
"hashbrown",
|
"hashbrown",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "instant"
|
|
||||||
version = "0.1.12"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
|
|
||||||
dependencies = [
|
|
||||||
"cfg-if",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "jobserver"
|
name = "jobserver"
|
||||||
version = "0.1.24"
|
version = "0.1.24"
|
||||||
@@ -292,15 +293,15 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.112"
|
version = "0.2.125"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125"
|
checksum = "5916d2ae698f6de9bfb891ad7a8d65c09d232dc58cc4ac433c7da3b2fd84bc2b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libgit2-sys"
|
name = "libgit2-sys"
|
||||||
version = "0.12.26+1.3.0"
|
version = "0.13.3+1.4.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "19e1c899248e606fbfe68dcb31d8b0176ebab833b103824af31bddf4b7457494"
|
checksum = "c24d36c3ac9b9996a2418d6bf428cc0bc5d1a814a84303fc60986088c5ed60de"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
"libc",
|
"libc",
|
||||||
@@ -326,9 +327,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libz-sys"
|
name = "libz-sys"
|
||||||
version = "1.1.3"
|
version = "1.1.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "de5435b8549c16d423ed0c03dbaafe57cf6c3344744f1242520d59c9d8ecec66"
|
checksum = "92e7e15d7610cce1d9752e137625f14e61a28cd45929b6e12e47b50fe154ee2e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
"libc",
|
"libc",
|
||||||
@@ -337,19 +338,26 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lock_api"
|
name = "linked-hash-map"
|
||||||
version = "0.4.5"
|
version = "0.5.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "712a4d093c9976e24e7dbca41db895dabcbac38eb5f4045393d17a95bdfb1109"
|
checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lock_api"
|
||||||
|
version = "0.4.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
"scopeguard",
|
"scopeguard",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "log"
|
name = "log"
|
||||||
version = "0.4.14"
|
version = "0.4.17"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
|
checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
]
|
]
|
||||||
@@ -362,20 +370,21 @@ checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memchr"
|
name = "memchr"
|
||||||
version = "2.4.1"
|
version = "2.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
|
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mio"
|
name = "mio"
|
||||||
version = "0.7.14"
|
version = "0.8.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8067b404fe97c70829f082dec8bcf4f71225d7eaea1d8645349cb76fa06205cc"
|
checksum = "52da4364ffb0e4fe33a9841a98a3f3014fb964045ce4f7a45a398243c8d6b0c9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"log",
|
"log",
|
||||||
"miow",
|
"miow",
|
||||||
"ntapi",
|
"ntapi",
|
||||||
|
"wasi 0.11.0+wasi-snapshot-preview1",
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -390,30 +399,30 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ntapi"
|
name = "ntapi"
|
||||||
version = "0.3.6"
|
version = "0.3.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3f6bb902e437b6d86e03cce10a7e2af662292c5dfef23b65899ea3ac9354ad44"
|
checksum = "c28774a7fd2fbb4f0babd8237ce554b73af68021b5f695a3cebd6c59bac0980f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "once_cell"
|
name = "once_cell"
|
||||||
version = "1.9.0"
|
version = "1.10.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5"
|
checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "openssl-probe"
|
name = "openssl-probe"
|
||||||
version = "0.1.4"
|
version = "0.1.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "28988d872ab76095a6e6ac88d99b54fd267702734fd7ffe610ca27f533ddb95a"
|
checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "openssl-sys"
|
name = "openssl-sys"
|
||||||
version = "0.9.72"
|
version = "0.9.73"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7e46109c383602735fa0a2e48dd2b7c892b048e1bf69e5c3b1d804b7d9c203cb"
|
checksum = "9d5fd19fb3e0a8191c1e34935718976a3e70c112ab9a24af6d7cadccd9d90bc0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
"cc",
|
"cc",
|
||||||
@@ -427,33 +436,28 @@ name = "os_str_bytes"
|
|||||||
version = "6.0.0"
|
version = "6.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8e22443d1643a904602595ba1cd8f7d896afe56d26712531c5ff73a15b2fbf64"
|
checksum = "8e22443d1643a904602595ba1cd8f7d896afe56d26712531c5ff73a15b2fbf64"
|
||||||
dependencies = [
|
|
||||||
"memchr",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "parking_lot"
|
name = "parking_lot"
|
||||||
version = "0.11.2"
|
version = "0.12.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99"
|
checksum = "87f5ec2493a61ac0506c0f4199f99070cbe83857b0337006a30f3e6719b8ef58"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"instant",
|
|
||||||
"lock_api",
|
"lock_api",
|
||||||
"parking_lot_core",
|
"parking_lot_core",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "parking_lot_core"
|
name = "parking_lot_core"
|
||||||
version = "0.8.5"
|
version = "0.9.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216"
|
checksum = "09a279cbf25cb0757810394fbc1e359949b59e348145c643a939a525692e6929"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"instant",
|
|
||||||
"libc",
|
"libc",
|
||||||
"redox_syscall",
|
"redox_syscall",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"winapi",
|
"windows-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -464,9 +468,9 @@ checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pkg-config"
|
name = "pkg-config"
|
||||||
version = "0.3.24"
|
version = "0.3.25"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "58893f751c9b0412871a09abd62ecd2a00298c6c83befa223ef98c52aef40cbe"
|
checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro-error"
|
name = "proc-macro-error"
|
||||||
@@ -494,18 +498,18 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.36"
|
version = "1.0.38"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029"
|
checksum = "9027b48e9d4c9175fa2218adf3557f91c1137021739951d4932f5f8268ac48aa"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"unicode-xid",
|
"unicode-xid",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "1.0.14"
|
version = "1.0.18"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "47aa80447ce4daf1717500037052af176af5d38cc3e571d9ec1c7353fc10c87d"
|
checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
@@ -549,28 +553,29 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "redox_syscall"
|
name = "redox_syscall"
|
||||||
version = "0.2.10"
|
version = "0.2.13"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff"
|
checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "redox_users"
|
name = "redox_users"
|
||||||
version = "0.4.0"
|
version = "0.4.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64"
|
checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"getrandom",
|
"getrandom",
|
||||||
"redox_syscall",
|
"redox_syscall",
|
||||||
|
"thiserror",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex"
|
name = "regex"
|
||||||
version = "1.5.4"
|
version = "1.5.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461"
|
checksum = "1a11647b6b25ff05a515cb92c365cec08801e83423a235b51e231e1808747286"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aho-corasick",
|
"aho-corasick",
|
||||||
"memchr",
|
"memchr",
|
||||||
@@ -592,6 +597,18 @@ dependencies = [
|
|||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustversion"
|
||||||
|
version = "1.0.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f2cc38e8fa666e2de3c4aba7edeb5ffc5246c1c2ed0e3d17e560aeeba736b23f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ryu"
|
||||||
|
version = "1.0.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "scopeguard"
|
name = "scopeguard"
|
||||||
version = "1.1.0"
|
version = "1.1.0"
|
||||||
@@ -600,24 +617,36 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.133"
|
version = "1.0.137"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "97565067517b60e2d1ea8b268e59ce036de907ac523ad83a0475da04e818989a"
|
checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_derive"
|
name = "serde_derive"
|
||||||
version = "1.0.133"
|
version = "1.0.137"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ed201699328568d8d08208fdd080e3ff594e6c422e438b6705905da01005d537"
|
checksum = "1f26faba0c3959972377d3b2d306ee9f71faee9714294e41bb777f83f88578be"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_yaml"
|
||||||
|
version = "0.8.24"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "707d15895415db6628332b737c838b88c598522e4dc70647e59b72312924aebc"
|
||||||
|
dependencies = [
|
||||||
|
"indexmap",
|
||||||
|
"ryu",
|
||||||
|
"serde",
|
||||||
|
"yaml-rust",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "shellexpand"
|
name = "shellexpand"
|
||||||
version = "2.1.0"
|
version = "2.1.0"
|
||||||
@@ -639,9 +668,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "signal-hook-mio"
|
name = "signal-hook-mio"
|
||||||
version = "0.2.1"
|
version = "0.2.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "29fd5867f1c4f2c5be079aee7a2adf1152ebb04a4bc4d341f504b7dece607ed4"
|
checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"mio",
|
"mio",
|
||||||
@@ -659,9 +688,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "smallvec"
|
name = "smallvec"
|
||||||
version = "1.7.0"
|
version = "1.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1ecab6c735a6bb4139c0caafd0cc3635748bbb3acf4550e8138122099251f309"
|
checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "strsim"
|
name = "strsim"
|
||||||
@@ -671,27 +700,28 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "strum"
|
name = "strum"
|
||||||
version = "0.22.0"
|
version = "0.23.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f7ac893c7d471c8a21f31cfe213ec4f6d9afeed25537c772e08ef3f005f8729e"
|
checksum = "cae14b91c7d11c9a851d3fbc80a963198998c2a64eec840477fa92d8ce9b70bb"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "strum_macros"
|
name = "strum_macros"
|
||||||
version = "0.22.0"
|
version = "0.23.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "339f799d8b549e3744c7ac7feb216383e4005d94bdb22561b3ab8f3b808ae9fb"
|
checksum = "5bb0dc7ee9c15cea6199cde9a127fa16a4c5819af85395457ad72d68edc85a38"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"heck 0.3.3",
|
"heck 0.3.3",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
"rustversion",
|
||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "1.0.85"
|
version = "1.0.92"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a684ac3dcd8913827e18cd09a68384ee66c1de24157e3c556c9ab16d85695fb7"
|
checksum = "7ff7c592601f11445996a06f8ad0c27f094a58857c2f89e97974ab9235b92c52"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@@ -710,9 +740,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "termcolor"
|
name = "termcolor"
|
||||||
version = "1.1.2"
|
version = "1.1.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4"
|
checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"winapi-util",
|
"winapi-util",
|
||||||
]
|
]
|
||||||
@@ -729,15 +759,35 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "textwrap"
|
name = "textwrap"
|
||||||
version = "0.14.2"
|
version = "0.15.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0066c8d12af8b5acd21e00547c3797fde4e8677254a7ee429176ccebbe93dd80"
|
checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thiserror"
|
||||||
|
version = "1.0.31"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bd829fe32373d27f76265620b5309d0340cb8550f523c1dda251d6298069069a"
|
||||||
|
dependencies = [
|
||||||
|
"thiserror-impl",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thiserror-impl"
|
||||||
|
version = "1.0.31"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0396bc89e626244658bef819e22d0cc459e795a5ebe878e6ec336d1674a8d79a"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tinyvec"
|
name = "tinyvec"
|
||||||
version = "1.5.1"
|
version = "1.6.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2c1c1d5a42b6245520c249549ec267180beaffcc0615401ac8e31853d4b6d8d2"
|
checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"tinyvec_macros",
|
"tinyvec_macros",
|
||||||
]
|
]
|
||||||
@@ -750,18 +800,18 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "toml"
|
name = "toml"
|
||||||
version = "0.5.8"
|
version = "0.5.9"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa"
|
checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-bidi"
|
name = "unicode-bidi"
|
||||||
version = "0.3.7"
|
version = "0.3.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1a01404663e3db436ed2746d9fefef640d868edae3cceb81c3b8d5732fda678f"
|
checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-normalization"
|
name = "unicode-normalization"
|
||||||
@@ -774,9 +824,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-segmentation"
|
name = "unicode-segmentation"
|
||||||
version = "1.8.0"
|
version = "1.9.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b"
|
checksum = "7e8820f5d777f6224dc4be3632222971ac30164d4a258d595640799554ebfd99"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-width"
|
name = "unicode-width"
|
||||||
@@ -786,9 +836,9 @@ checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-xid"
|
name = "unicode-xid"
|
||||||
version = "0.2.2"
|
version = "0.2.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
|
checksum = "957e51f3646910546462e67d5f7599b9e4fb8acdd304b087a6494730f9eebf04"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "url"
|
name = "url"
|
||||||
@@ -820,6 +870,12 @@ version = "0.10.2+wasi-snapshot-preview1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
|
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasi"
|
||||||
|
version = "0.11.0+wasi-snapshot-preview1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winapi"
|
name = "winapi"
|
||||||
version = "0.3.9"
|
version = "0.3.9"
|
||||||
@@ -850,3 +906,55 @@ name = "winapi-x86_64-pc-windows-gnu"
|
|||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-sys"
|
||||||
|
version = "0.36.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2"
|
||||||
|
dependencies = [
|
||||||
|
"windows_aarch64_msvc",
|
||||||
|
"windows_i686_gnu",
|
||||||
|
"windows_i686_msvc",
|
||||||
|
"windows_x86_64_gnu",
|
||||||
|
"windows_x86_64_msvc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_aarch64_msvc"
|
||||||
|
version = "0.36.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_gnu"
|
||||||
|
version = "0.36.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_msvc"
|
||||||
|
version = "0.36.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_gnu"
|
||||||
|
version = "0.36.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_msvc"
|
||||||
|
version = "0.36.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "yaml-rust"
|
||||||
|
version = "0.4.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85"
|
||||||
|
dependencies = [
|
||||||
|
"linked-hash-map",
|
||||||
|
]
|
||||||
|
|||||||
17
Cargo.toml
17
Cargo.toml
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "git-repo-manager"
|
name = "git-repo-manager"
|
||||||
version = "0.5.0"
|
version = "0.6.2"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
authors = [
|
authors = [
|
||||||
"Hannes Körber <hannes@hkoerber.de>",
|
"Hannes Körber <hannes@hkoerber.de>",
|
||||||
@@ -37,30 +37,33 @@ path = "src/grm/main.rs"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
|
|
||||||
[dependencies.toml]
|
[dependencies.toml]
|
||||||
version = "=0.5.8"
|
version = "=0.5.9"
|
||||||
|
|
||||||
[dependencies.serde]
|
[dependencies.serde]
|
||||||
version = "=1.0.133"
|
version = "=1.0.137"
|
||||||
features = ["derive"]
|
features = ["derive"]
|
||||||
|
|
||||||
[dependencies.git2]
|
[dependencies.git2]
|
||||||
version = "=0.13.25"
|
version = "=0.14.3"
|
||||||
|
|
||||||
[dependencies.shellexpand]
|
[dependencies.shellexpand]
|
||||||
version = "=2.1.0"
|
version = "=2.1.0"
|
||||||
|
|
||||||
[dependencies.clap]
|
[dependencies.clap]
|
||||||
version = "=3.0.5"
|
version = "=3.1.17"
|
||||||
features = ["derive", "cargo"]
|
features = ["derive", "cargo"]
|
||||||
|
|
||||||
[dependencies.console]
|
[dependencies.console]
|
||||||
version = "=0.15.0"
|
version = "=0.15.0"
|
||||||
|
|
||||||
[dependencies.regex]
|
[dependencies.regex]
|
||||||
version = "=1.5.4"
|
version = "=1.5.5"
|
||||||
|
|
||||||
[dependencies.comfy-table]
|
[dependencies.comfy-table]
|
||||||
version = "=5.0.0"
|
version = "=5.0.1"
|
||||||
|
|
||||||
|
[dependencies.serde_yaml]
|
||||||
|
version = "=0.8.24"
|
||||||
|
|
||||||
[dev-dependencies.tempdir]
|
[dev-dependencies.tempdir]
|
||||||
version = "=0.3.7"
|
version = "=0.3.7"
|
||||||
|
|||||||
3
Justfile
3
Justfile
@@ -52,3 +52,6 @@ check-pip-requirements: e2e-venv
|
|||||||
@cd ./e2e_tests \
|
@cd ./e2e_tests \
|
||||||
&& . ./venv/bin/activate \
|
&& . ./venv/bin/activate \
|
||||||
&& pip list --outdated | grep -q '.' && exit 1 || exit 0
|
&& pip list --outdated | grep -q '.' && exit 1 || exit 0
|
||||||
|
|
||||||
|
clean:
|
||||||
|
cargo clean
|
||||||
|
|||||||
@@ -14,7 +14,13 @@ AUTOUPDATE_DISABLED = []
|
|||||||
|
|
||||||
if os.path.exists(INDEX_DIR):
|
if os.path.exists(INDEX_DIR):
|
||||||
subprocess.run(
|
subprocess.run(
|
||||||
["git", "pull", "--depth=1", "origin"],
|
["git", "fetch", "--depth=1", "origin"],
|
||||||
|
cwd=INDEX_DIR,
|
||||||
|
check=True,
|
||||||
|
capture_output=True,
|
||||||
|
)
|
||||||
|
subprocess.run(
|
||||||
|
["git", "reset", "--hard", "origin/master"],
|
||||||
cwd=INDEX_DIR,
|
cwd=INDEX_DIR,
|
||||||
check=True,
|
check=True,
|
||||||
capture_output=True,
|
capture_output=True,
|
||||||
@@ -33,7 +39,7 @@ update_necessary = False
|
|||||||
|
|
||||||
# This updates the crates.io index, see https://github.com/rust-lang/cargo/issues/3377
|
# This updates the crates.io index, see https://github.com/rust-lang/cargo/issues/3377
|
||||||
subprocess.run(
|
subprocess.run(
|
||||||
["cargo", "search", "--limit", "0"],
|
["cargo", "update", "--dry-run"],
|
||||||
check=True,
|
check=True,
|
||||||
capture_output=False, # to get some git output
|
capture_output=False, # to get some git output
|
||||||
)
|
)
|
||||||
@@ -55,10 +61,11 @@ for tier in ["dependencies", "dev-dependencies"]:
|
|||||||
latest_version = None
|
latest_version = None
|
||||||
for version_entry in open(info_file, "r").readlines():
|
for version_entry in open(info_file, "r").readlines():
|
||||||
version = semver.VersionInfo.parse(json.loads(version_entry)["vers"])
|
version = semver.VersionInfo.parse(json.loads(version_entry)["vers"])
|
||||||
if current_version.prerelease == "" and version.prerelease != "":
|
|
||||||
# skip prereleases, except when we are on a prerelease already
|
|
||||||
continue
|
|
||||||
if latest_version is None or version > latest_version:
|
if latest_version is None or version > latest_version:
|
||||||
|
if current_version.prerelease is None and version.prerelease is not None:
|
||||||
|
# skip prereleases, except when we are on a prerelease already
|
||||||
|
print(f"{name}: Skipping prerelease version {version}")
|
||||||
|
continue
|
||||||
latest_version = version
|
latest_version = version
|
||||||
|
|
||||||
if latest_version != current_version:
|
if latest_version != current_version:
|
||||||
|
|||||||
@@ -5,7 +5,8 @@ Manager](https://github.com/hakoerber/git-repo-manager/) (GRM for short), a
|
|||||||
tool that helps you manage git repositories.
|
tool that helps you manage git repositories.
|
||||||
|
|
||||||
GRM helps you manage git repositories in a declarative way. Configure your
|
GRM helps you manage git repositories in a declarative way. Configure your
|
||||||
repositories in a TOML file, GRM does the rest. Take a look at [the example
|
repositories in a TOML or YAML file, GRM does the rest. Take a look at [the
|
||||||
|
example
|
||||||
configuration](https://github.com/hakoerber/git-repo-manager/blob/master/example.config.toml)
|
configuration](https://github.com/hakoerber/git-repo-manager/blob/master/example.config.toml)
|
||||||
to get a feel for the way you configure your repositories. See the [repository
|
to get a feel for the way you configure your repositories. See the [repository
|
||||||
tree chapter](./repos.md) for details.
|
tree chapter](./repos.md) for details.
|
||||||
|
|||||||
@@ -74,3 +74,9 @@ $ grm repos status
|
|||||||
╰──────────┴──────────┴────────┴──────────┴───────┴─────────╯
|
╰──────────┴──────────┴────────┴──────────┴───────┴─────────╯
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## YAML
|
||||||
|
|
||||||
|
By default, the repo configuration uses TOML. If you prefer YAML, just give it
|
||||||
|
a YAML file instead (file ending does not matter, `grm` will figure out the format
|
||||||
|
itself). For generating a configuration, pass `--format yaml` to `grm repo find`
|
||||||
|
to generate YAML instead of TOML.
|
||||||
|
|||||||
@@ -309,6 +309,10 @@ grm wt pull --rebase
|
|||||||
[✔] my-cool-branch: Done
|
[✔] my-cool-branch: Done
|
||||||
```
|
```
|
||||||
|
|
||||||
|
As noted, this will fail if there are any local changes in your worktree. If you
|
||||||
|
want to stash these changes automatically before the pull (and unstash them
|
||||||
|
afterwards), use the `--stash` option.
|
||||||
|
|
||||||
This will rebase your changes onto the upstream branch. This is mainly helpful
|
This will rebase your changes onto the upstream branch. This is mainly helpful
|
||||||
for persistent branches that change on the remote side.
|
for persistent branches that change on the remote side.
|
||||||
|
|
||||||
@@ -346,6 +350,10 @@ run two commands.
|
|||||||
I understand that the UX is not the most intuitive. If you can think of an
|
I understand that the UX is not the most intuitive. If you can think of an
|
||||||
improvement, please let me know (e.g. via an GitHub issue)!
|
improvement, please let me know (e.g. via an GitHub issue)!
|
||||||
|
|
||||||
|
As with `pull`, `rebase` will also refuse to run when there are changes in your
|
||||||
|
worktree. And you can also use the `--stash` option to stash/unstash changes
|
||||||
|
automatically.
|
||||||
|
|
||||||
### Manual access
|
### Manual access
|
||||||
|
|
||||||
GRM isn't doing any magic, it's just git under the hood. If you need to have access
|
GRM isn't doing any magic, it's just git under the hood. If you need to have access
|
||||||
|
|||||||
@@ -1,12 +1,14 @@
|
|||||||
attrs==21.4.0
|
attrs==21.4.0
|
||||||
gitdb==4.0.9
|
gitdb==4.0.9
|
||||||
GitPython==3.1.25
|
GitPython==3.1.27
|
||||||
iniconfig==1.1.1
|
iniconfig==1.1.1
|
||||||
packaging==21.3
|
packaging==21.3
|
||||||
pluggy==1.0.0
|
pluggy==1.0.0
|
||||||
py==1.11.0
|
py==1.11.0
|
||||||
pyparsing==3.0.6
|
pyparsing==3.0.8
|
||||||
pytest==6.2.5
|
pytest==7.1.2
|
||||||
|
PyYAML==6.0
|
||||||
smmap==5.0.0
|
smmap==5.0.0
|
||||||
toml==0.10.2
|
toml==0.10.2
|
||||||
typing_extensions==4.0.1
|
tomli==2.0.1
|
||||||
|
typing_extensions==4.2.0
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
import tempfile
|
import tempfile
|
||||||
|
|
||||||
import toml
|
import toml
|
||||||
|
import pytest
|
||||||
|
import yaml
|
||||||
|
|
||||||
from helpers import *
|
from helpers import *
|
||||||
|
|
||||||
@@ -30,6 +32,16 @@ def test_repos_find_empty():
|
|||||||
assert len(cmd.stderr) != 0
|
assert len(cmd.stderr) != 0
|
||||||
|
|
||||||
|
|
||||||
|
def test_repos_find_invalid_format():
|
||||||
|
with tempfile.TemporaryDirectory() as tmpdir:
|
||||||
|
cmd = grm(
|
||||||
|
["repos", "find", tmpdir, "--format", "invalidformat"], is_invalid=True
|
||||||
|
)
|
||||||
|
assert cmd.returncode != 0
|
||||||
|
assert len(cmd.stdout) == 0
|
||||||
|
assert "isn't a valid value" in cmd.stderr
|
||||||
|
|
||||||
|
|
||||||
def test_repos_find_non_git_repos():
|
def test_repos_find_non_git_repos():
|
||||||
with tempfile.TemporaryDirectory() as tmpdir:
|
with tempfile.TemporaryDirectory() as tmpdir:
|
||||||
shell(
|
shell(
|
||||||
@@ -50,7 +62,9 @@ def test_repos_find_non_git_repos():
|
|||||||
assert len(cmd.stderr) != 0
|
assert len(cmd.stderr) != 0
|
||||||
|
|
||||||
|
|
||||||
def test_repos_find():
|
@pytest.mark.parametrize("default", [True, False])
|
||||||
|
@pytest.mark.parametrize("configtype", ["toml", "yaml"])
|
||||||
|
def test_repos_find(configtype, default):
|
||||||
with tempfile.TemporaryDirectory() as tmpdir:
|
with tempfile.TemporaryDirectory() as tmpdir:
|
||||||
shell(
|
shell(
|
||||||
f"""
|
f"""
|
||||||
@@ -83,11 +97,19 @@ def test_repos_find():
|
|||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
|
|
||||||
cmd = grm(["repos", "find", tmpdir])
|
args = ["repos", "find", tmpdir]
|
||||||
|
if not default:
|
||||||
|
args += ["--format", configtype]
|
||||||
|
cmd = grm(args)
|
||||||
assert cmd.returncode == 0
|
assert cmd.returncode == 0
|
||||||
assert len(cmd.stderr) == 0
|
assert len(cmd.stderr) == 0
|
||||||
|
|
||||||
output = toml.loads(cmd.stdout)
|
if default or configtype == "toml":
|
||||||
|
output = toml.loads(cmd.stdout)
|
||||||
|
elif configtype == "yaml":
|
||||||
|
output = yaml.safe_load(cmd.stdout)
|
||||||
|
else:
|
||||||
|
raise NotImplementedError()
|
||||||
|
|
||||||
assert isinstance(output, dict)
|
assert isinstance(output, dict)
|
||||||
assert set(output.keys()) == {"trees"}
|
assert set(output.keys()) == {"trees"}
|
||||||
@@ -125,14 +147,24 @@ def test_repos_find():
|
|||||||
assert origin["url"] == "https://example.com/repo2.git"
|
assert origin["url"] == "https://example.com/repo2.git"
|
||||||
|
|
||||||
|
|
||||||
def test_repos_find_in_root():
|
@pytest.mark.parametrize("default", [True, False])
|
||||||
|
@pytest.mark.parametrize("configtype", ["toml", "yaml"])
|
||||||
|
def test_repos_find_in_root(configtype, default):
|
||||||
with TempGitRepository() as repo_dir:
|
with TempGitRepository() as repo_dir:
|
||||||
|
|
||||||
cmd = grm(["repos", "find", repo_dir])
|
args = ["repos", "find", repo_dir]
|
||||||
|
if not default:
|
||||||
|
args += ["--format", configtype]
|
||||||
|
cmd = grm(args)
|
||||||
assert cmd.returncode == 0
|
assert cmd.returncode == 0
|
||||||
assert len(cmd.stderr) == 0
|
assert len(cmd.stderr) == 0
|
||||||
|
|
||||||
output = toml.loads(cmd.stdout)
|
if default or configtype == "toml":
|
||||||
|
output = toml.loads(cmd.stdout)
|
||||||
|
elif configtype == "yaml":
|
||||||
|
output = yaml.safe_load(cmd.stdout)
|
||||||
|
else:
|
||||||
|
raise NotImplementedError()
|
||||||
|
|
||||||
assert isinstance(output, dict)
|
assert isinstance(output, dict)
|
||||||
assert set(output.keys()) == {"trees"}
|
assert set(output.keys()) == {"trees"}
|
||||||
@@ -160,7 +192,9 @@ def test_repos_find_in_root():
|
|||||||
assert someremote["type"] == "file"
|
assert someremote["type"] == "file"
|
||||||
|
|
||||||
|
|
||||||
def test_repos_find_with_invalid_repo():
|
@pytest.mark.parametrize("configtype", ["toml", "yaml"])
|
||||||
|
@pytest.mark.parametrize("default", [True, False])
|
||||||
|
def test_repos_find_with_invalid_repo(configtype, default):
|
||||||
with tempfile.TemporaryDirectory() as tmpdir:
|
with tempfile.TemporaryDirectory() as tmpdir:
|
||||||
shell(
|
shell(
|
||||||
f"""
|
f"""
|
||||||
@@ -193,11 +227,19 @@ def test_repos_find_with_invalid_repo():
|
|||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
|
|
||||||
cmd = grm(["repos", "find", tmpdir])
|
args = ["repos", "find", tmpdir]
|
||||||
|
if not default:
|
||||||
|
args += ["--format", configtype]
|
||||||
|
cmd = grm(args)
|
||||||
assert cmd.returncode == 0
|
assert cmd.returncode == 0
|
||||||
assert "broken" in cmd.stderr
|
assert "broken" in cmd.stderr
|
||||||
|
|
||||||
output = toml.loads(cmd.stdout)
|
if default or configtype == "toml":
|
||||||
|
output = toml.loads(cmd.stdout)
|
||||||
|
elif configtype == "yaml":
|
||||||
|
output = yaml.safe_load(cmd.stdout)
|
||||||
|
else:
|
||||||
|
raise NotImplementedError()
|
||||||
|
|
||||||
assert isinstance(output, dict)
|
assert isinstance(output, dict)
|
||||||
assert set(output.keys()) == {"trees"}
|
assert set(output.keys()) == {"trees"}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
import tempfile
|
import tempfile
|
||||||
import re
|
import re
|
||||||
|
import textwrap
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
import toml
|
import toml
|
||||||
@@ -9,8 +10,134 @@ import git
|
|||||||
|
|
||||||
from helpers import *
|
from helpers import *
|
||||||
|
|
||||||
|
templates = {
|
||||||
|
"repo_simple": {
|
||||||
|
"toml": """
|
||||||
|
[[trees]]
|
||||||
|
root = "{root}"
|
||||||
|
|
||||||
def test_repos_sync_config_is_valid_symlink():
|
[[trees.repos]]
|
||||||
|
name = "test"
|
||||||
|
""",
|
||||||
|
"yaml": """
|
||||||
|
trees:
|
||||||
|
- root: "{root}"
|
||||||
|
repos:
|
||||||
|
- name: "test"
|
||||||
|
""",
|
||||||
|
},
|
||||||
|
"repo_with_remote": {
|
||||||
|
"toml": """
|
||||||
|
[[trees]]
|
||||||
|
root = "{root}"
|
||||||
|
|
||||||
|
[[trees.repos]]
|
||||||
|
name = "test"
|
||||||
|
|
||||||
|
[[trees.repos.remotes]]
|
||||||
|
name = "{remotename}"
|
||||||
|
url = "file://{remote}"
|
||||||
|
type = "file"
|
||||||
|
""",
|
||||||
|
"yaml": textwrap.dedent(
|
||||||
|
"""
|
||||||
|
trees:
|
||||||
|
- root: "{root}"
|
||||||
|
repos:
|
||||||
|
- name: test
|
||||||
|
remotes:
|
||||||
|
- name: "{remotename}"
|
||||||
|
url: "file://{remote}"
|
||||||
|
type: "file"
|
||||||
|
"""
|
||||||
|
),
|
||||||
|
},
|
||||||
|
"repo_with_two_remotes": {
|
||||||
|
"toml": """
|
||||||
|
[[trees]]
|
||||||
|
root = "{root}"
|
||||||
|
|
||||||
|
[[trees.repos]]
|
||||||
|
name = "test"
|
||||||
|
|
||||||
|
[[trees.repos.remotes]]
|
||||||
|
name = "origin"
|
||||||
|
url = "file://{remote1}"
|
||||||
|
type = "file"
|
||||||
|
|
||||||
|
[[trees.repos.remotes]]
|
||||||
|
name = "origin2"
|
||||||
|
url = "file://{remote2}"
|
||||||
|
type = "file"
|
||||||
|
""",
|
||||||
|
"yaml": textwrap.dedent(
|
||||||
|
"""
|
||||||
|
trees:
|
||||||
|
- root: "{root}"
|
||||||
|
repos:
|
||||||
|
- name: "test"
|
||||||
|
remotes:
|
||||||
|
- name: "origin"
|
||||||
|
url: "file://{remote1}"
|
||||||
|
type: "file"
|
||||||
|
- name: "origin2"
|
||||||
|
url: "file://{remote2}"
|
||||||
|
type: "file"
|
||||||
|
"""
|
||||||
|
),
|
||||||
|
},
|
||||||
|
"worktree_repo_simple": {
|
||||||
|
"toml": """
|
||||||
|
[[trees]]
|
||||||
|
root = "{root}"
|
||||||
|
|
||||||
|
[[trees.repos]]
|
||||||
|
name = "test"
|
||||||
|
worktree_setup = true
|
||||||
|
""",
|
||||||
|
"yaml": textwrap.dedent(
|
||||||
|
"""
|
||||||
|
trees:
|
||||||
|
- root: "{root}"
|
||||||
|
repos:
|
||||||
|
- name: test
|
||||||
|
worktree_setup: true
|
||||||
|
"""
|
||||||
|
),
|
||||||
|
},
|
||||||
|
"worktree_repo_with_remote": {
|
||||||
|
"toml": """
|
||||||
|
[[trees]]
|
||||||
|
root = "{root}"
|
||||||
|
|
||||||
|
[[trees.repos]]
|
||||||
|
name = "test"
|
||||||
|
worktree_setup = true
|
||||||
|
|
||||||
|
[[trees.repos.remotes]]
|
||||||
|
name = "origin"
|
||||||
|
url = "file://{remote}"
|
||||||
|
type = "file"
|
||||||
|
""",
|
||||||
|
"yaml": textwrap.dedent(
|
||||||
|
"""
|
||||||
|
trees:
|
||||||
|
- root: "{root}"
|
||||||
|
repos:
|
||||||
|
- name: test
|
||||||
|
worktree_setup: true
|
||||||
|
remotes:
|
||||||
|
- name: origin
|
||||||
|
url: "file://{remote}"
|
||||||
|
type: "file"
|
||||||
|
"""
|
||||||
|
),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("configtype", ["toml", "yaml"])
|
||||||
|
def test_repos_sync_config_is_valid_symlink(configtype):
|
||||||
with tempfile.TemporaryDirectory() as target:
|
with tempfile.TemporaryDirectory() as target:
|
||||||
with TempGitFileRemote() as (remote, head_commit_sha):
|
with TempGitFileRemote() as (remote, head_commit_sha):
|
||||||
with tempfile.NamedTemporaryFile() as config:
|
with tempfile.NamedTemporaryFile() as config:
|
||||||
@@ -20,20 +147,13 @@ def test_repos_sync_config_is_valid_symlink():
|
|||||||
|
|
||||||
with open(config.name, "w") as f:
|
with open(config.name, "w") as f:
|
||||||
f.write(
|
f.write(
|
||||||
f"""
|
templates["repo_with_remote"][configtype].format(
|
||||||
[[trees]]
|
root=target, remote=remote, remotename="origin"
|
||||||
root = "{target}"
|
)
|
||||||
|
|
||||||
[[trees.repos]]
|
|
||||||
name = "test"
|
|
||||||
|
|
||||||
[[trees.repos.remotes]]
|
|
||||||
name = "origin"
|
|
||||||
url = "file://{remote}"
|
|
||||||
type = "file"
|
|
||||||
"""
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
subprocess.run(["cat", config.name])
|
||||||
|
|
||||||
cmd = grm(["repos", "sync", "--config", config_symlink])
|
cmd = grm(["repos", "sync", "--config", config_symlink])
|
||||||
assert cmd.returncode == 0
|
assert cmd.returncode == 0
|
||||||
|
|
||||||
@@ -85,20 +205,13 @@ def test_repos_sync_config_is_unreadable():
|
|||||||
assert "permission denied" in cmd.stderr.lower()
|
assert "permission denied" in cmd.stderr.lower()
|
||||||
|
|
||||||
|
|
||||||
def test_repos_sync_unmanaged_repos():
|
@pytest.mark.parametrize("configtype", ["toml", "yaml"])
|
||||||
|
def test_repos_sync_unmanaged_repos(configtype):
|
||||||
with tempfile.TemporaryDirectory() as root:
|
with tempfile.TemporaryDirectory() as root:
|
||||||
with TempGitRepository(dir=root) as unmanaged_repo:
|
with TempGitRepository(dir=root) as unmanaged_repo:
|
||||||
with tempfile.NamedTemporaryFile() as config:
|
with tempfile.NamedTemporaryFile() as config:
|
||||||
with open(config.name, "w") as f:
|
with open(config.name, "w") as f:
|
||||||
f.write(
|
f.write(templates["repo_simple"][configtype].format(root=root))
|
||||||
f"""
|
|
||||||
[[trees]]
|
|
||||||
root = "{root}"
|
|
||||||
|
|
||||||
[[trees.repos]]
|
|
||||||
name = "test"
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
|
|
||||||
cmd = grm(["repos", "sync", "--config", config.name])
|
cmd = grm(["repos", "sync", "--config", config.name])
|
||||||
assert cmd.returncode == 0
|
assert cmd.returncode == 0
|
||||||
@@ -112,19 +225,12 @@ def test_repos_sync_unmanaged_repos():
|
|||||||
assert any([re.match(regex, l) for l in cmd.stderr.lower().split("\n")])
|
assert any([re.match(regex, l) for l in cmd.stderr.lower().split("\n")])
|
||||||
|
|
||||||
|
|
||||||
def test_repos_sync_root_is_file():
|
@pytest.mark.parametrize("configtype", ["toml", "yaml"])
|
||||||
|
def test_repos_sync_root_is_file(configtype):
|
||||||
with tempfile.NamedTemporaryFile() as target:
|
with tempfile.NamedTemporaryFile() as target:
|
||||||
with tempfile.NamedTemporaryFile() as config:
|
with tempfile.NamedTemporaryFile() as config:
|
||||||
with open(config.name, "w") as f:
|
with open(config.name, "w") as f:
|
||||||
f.write(
|
f.write(templates["repo_simple"][configtype].format(root=target.name))
|
||||||
f"""
|
|
||||||
[[trees]]
|
|
||||||
root = "{target.name}"
|
|
||||||
|
|
||||||
[[trees.repos]]
|
|
||||||
name = "test"
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
|
|
||||||
cmd = grm(["repos", "sync", "--config", config.name])
|
cmd = grm(["repos", "sync", "--config", config.name])
|
||||||
assert cmd.returncode != 0
|
assert cmd.returncode != 0
|
||||||
@@ -132,30 +238,17 @@ def test_repos_sync_root_is_file():
|
|||||||
assert "not a directory" in cmd.stderr.lower()
|
assert "not a directory" in cmd.stderr.lower()
|
||||||
|
|
||||||
|
|
||||||
def test_repos_sync_normal_clone():
|
@pytest.mark.parametrize("configtype", ["toml", "yaml"])
|
||||||
|
def test_repos_sync_normal_clone(configtype):
|
||||||
with tempfile.TemporaryDirectory() as target:
|
with tempfile.TemporaryDirectory() as target:
|
||||||
with TempGitFileRemote() as (remote1, remote1_head_commit_sha):
|
with TempGitFileRemote() as (remote1, remote1_head_commit_sha):
|
||||||
with TempGitFileRemote() as (remote2, remote2_head_commit_sha):
|
with TempGitFileRemote() as (remote2, remote2_head_commit_sha):
|
||||||
with tempfile.NamedTemporaryFile() as config:
|
with tempfile.NamedTemporaryFile() as config:
|
||||||
with open(config.name, "w") as f:
|
with open(config.name, "w") as f:
|
||||||
f.write(
|
f.write(
|
||||||
f"""
|
templates["repo_with_two_remotes"][configtype].format(
|
||||||
[[trees]]
|
root=target, remote1=remote1, remote2=remote2
|
||||||
root = "{target}"
|
)
|
||||||
|
|
||||||
[[trees.repos]]
|
|
||||||
name = "test"
|
|
||||||
|
|
||||||
[[trees.repos.remotes]]
|
|
||||||
name = "origin"
|
|
||||||
url = "file://{remote1}"
|
|
||||||
type = "file"
|
|
||||||
|
|
||||||
[[trees.repos.remotes]]
|
|
||||||
name = "origin2"
|
|
||||||
url = "file://{remote2}"
|
|
||||||
type = "file"
|
|
||||||
"""
|
|
||||||
)
|
)
|
||||||
|
|
||||||
cmd = grm(["repos", "sync", "--config", config.name])
|
cmd = grm(["repos", "sync", "--config", config.name])
|
||||||
@@ -183,19 +276,12 @@ def test_repos_sync_normal_clone():
|
|||||||
assert urls[0] == f"file://{remote2}"
|
assert urls[0] == f"file://{remote2}"
|
||||||
|
|
||||||
|
|
||||||
def test_repos_sync_normal_init():
|
@pytest.mark.parametrize("configtype", ["toml", "yaml"])
|
||||||
|
def test_repos_sync_normal_init(configtype):
|
||||||
with tempfile.TemporaryDirectory() as target:
|
with tempfile.TemporaryDirectory() as target:
|
||||||
with tempfile.NamedTemporaryFile() as config:
|
with tempfile.NamedTemporaryFile() as config:
|
||||||
with open(config.name, "w") as f:
|
with open(config.name, "w") as f:
|
||||||
f.write(
|
f.write(templates["repo_simple"][configtype].format(root=target))
|
||||||
f"""
|
|
||||||
[[trees]]
|
|
||||||
root = "{target}"
|
|
||||||
|
|
||||||
[[trees.repos]]
|
|
||||||
name = "test"
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
|
|
||||||
cmd = grm(["repos", "sync", "--config", config.name])
|
cmd = grm(["repos", "sync", "--config", config.name])
|
||||||
assert cmd.returncode == 0
|
assert cmd.returncode == 0
|
||||||
@@ -210,25 +296,17 @@ def test_repos_sync_normal_init():
|
|||||||
assert not repo.head.is_valid()
|
assert not repo.head.is_valid()
|
||||||
|
|
||||||
|
|
||||||
def test_repos_sync_normal_add_remote():
|
@pytest.mark.parametrize("configtype", ["toml", "yaml"])
|
||||||
|
def test_repos_sync_normal_add_remote(configtype):
|
||||||
with tempfile.TemporaryDirectory() as target:
|
with tempfile.TemporaryDirectory() as target:
|
||||||
with TempGitFileRemote() as (remote1, remote1_head_commit_sha):
|
with TempGitFileRemote() as (remote1, remote1_head_commit_sha):
|
||||||
with TempGitFileRemote() as (remote2, remote2_head_commit_sha):
|
with TempGitFileRemote() as (remote2, remote2_head_commit_sha):
|
||||||
with tempfile.NamedTemporaryFile() as config:
|
with tempfile.NamedTemporaryFile() as config:
|
||||||
with open(config.name, "w") as f:
|
with open(config.name, "w") as f:
|
||||||
f.write(
|
f.write(
|
||||||
f"""
|
templates["repo_with_remote"][configtype].format(
|
||||||
[[trees]]
|
root=target, remote=remote1, remotename="origin"
|
||||||
root = "{target}"
|
)
|
||||||
|
|
||||||
[[trees.repos]]
|
|
||||||
name = "test"
|
|
||||||
|
|
||||||
[[trees.repos.remotes]]
|
|
||||||
name = "origin"
|
|
||||||
url = "file://{remote1}"
|
|
||||||
type = "file"
|
|
||||||
"""
|
|
||||||
)
|
)
|
||||||
|
|
||||||
cmd = grm(["repos", "sync", "--config", config.name])
|
cmd = grm(["repos", "sync", "--config", config.name])
|
||||||
@@ -246,23 +324,9 @@ def test_repos_sync_normal_add_remote():
|
|||||||
|
|
||||||
with open(config.name, "w") as f:
|
with open(config.name, "w") as f:
|
||||||
f.write(
|
f.write(
|
||||||
f"""
|
templates["repo_with_two_remotes"][configtype].format(
|
||||||
[[trees]]
|
root=target, remote1=remote1, remote2=remote2
|
||||||
root = "{target}"
|
)
|
||||||
|
|
||||||
[[trees.repos]]
|
|
||||||
name = "test"
|
|
||||||
|
|
||||||
[[trees.repos.remotes]]
|
|
||||||
name = "origin"
|
|
||||||
url = "file://{remote1}"
|
|
||||||
type = "file"
|
|
||||||
|
|
||||||
[[trees.repos.remotes]]
|
|
||||||
name = "origin2"
|
|
||||||
url = "file://{remote2}"
|
|
||||||
type = "file"
|
|
||||||
"""
|
|
||||||
)
|
)
|
||||||
|
|
||||||
cmd = grm(["repos", "sync", "--config", config.name])
|
cmd = grm(["repos", "sync", "--config", config.name])
|
||||||
@@ -282,30 +346,17 @@ def test_repos_sync_normal_add_remote():
|
|||||||
assert urls[0] == f"file://{remote2}"
|
assert urls[0] == f"file://{remote2}"
|
||||||
|
|
||||||
|
|
||||||
def test_repos_sync_normal_remove_remote():
|
@pytest.mark.parametrize("configtype", ["toml", "yaml"])
|
||||||
|
def test_repos_sync_normal_remove_remote(configtype):
|
||||||
with tempfile.TemporaryDirectory() as target:
|
with tempfile.TemporaryDirectory() as target:
|
||||||
with TempGitFileRemote() as (remote1, remote1_head_commit_sha):
|
with TempGitFileRemote() as (remote1, remote1_head_commit_sha):
|
||||||
with TempGitFileRemote() as (remote2, remote2_head_commit_sha):
|
with TempGitFileRemote() as (remote2, remote2_head_commit_sha):
|
||||||
with tempfile.NamedTemporaryFile() as config:
|
with tempfile.NamedTemporaryFile() as config:
|
||||||
with open(config.name, "w") as f:
|
with open(config.name, "w") as f:
|
||||||
f.write(
|
f.write(
|
||||||
f"""
|
templates["repo_with_two_remotes"][configtype].format(
|
||||||
[[trees]]
|
root=target, remote1=remote1, remote2=remote2
|
||||||
root = "{target}"
|
)
|
||||||
|
|
||||||
[[trees.repos]]
|
|
||||||
name = "test"
|
|
||||||
|
|
||||||
[[trees.repos.remotes]]
|
|
||||||
name = "origin"
|
|
||||||
url = "file://{remote1}"
|
|
||||||
type = "file"
|
|
||||||
|
|
||||||
[[trees.repos.remotes]]
|
|
||||||
name = "origin2"
|
|
||||||
url = "file://{remote2}"
|
|
||||||
type = "file"
|
|
||||||
"""
|
|
||||||
)
|
)
|
||||||
|
|
||||||
cmd = grm(["repos", "sync", "--config", config.name])
|
cmd = grm(["repos", "sync", "--config", config.name])
|
||||||
@@ -326,18 +377,9 @@ def test_repos_sync_normal_remove_remote():
|
|||||||
|
|
||||||
with open(config.name, "w") as f:
|
with open(config.name, "w") as f:
|
||||||
f.write(
|
f.write(
|
||||||
f"""
|
templates["repo_with_remote"][configtype].format(
|
||||||
[[trees]]
|
root=target, remote=remote2, remotename="origin2"
|
||||||
root = "{target}"
|
)
|
||||||
|
|
||||||
[[trees.repos]]
|
|
||||||
name = "test"
|
|
||||||
|
|
||||||
[[trees.repos.remotes]]
|
|
||||||
name = "origin2"
|
|
||||||
url = "file://{remote2}"
|
|
||||||
type = "file"
|
|
||||||
"""
|
|
||||||
)
|
)
|
||||||
|
|
||||||
cmd = grm(["repos", "sync", "--config", config.name])
|
cmd = grm(["repos", "sync", "--config", config.name])
|
||||||
@@ -369,25 +411,17 @@ def test_repos_sync_normal_remove_remote():
|
|||||||
assert urls[0] == f"file://{remote2}"
|
assert urls[0] == f"file://{remote2}"
|
||||||
|
|
||||||
|
|
||||||
def test_repos_sync_normal_change_remote_url():
|
@pytest.mark.parametrize("configtype", ["toml", "yaml"])
|
||||||
|
def test_repos_sync_normal_change_remote_url(configtype):
|
||||||
with tempfile.TemporaryDirectory() as target:
|
with tempfile.TemporaryDirectory() as target:
|
||||||
with TempGitFileRemote() as (remote1, remote1_head_commit_sha):
|
with TempGitFileRemote() as (remote1, remote1_head_commit_sha):
|
||||||
with TempGitFileRemote() as (remote2, remote2_head_commit_sha):
|
with TempGitFileRemote() as (remote2, remote2_head_commit_sha):
|
||||||
with tempfile.NamedTemporaryFile() as config:
|
with tempfile.NamedTemporaryFile() as config:
|
||||||
with open(config.name, "w") as f:
|
with open(config.name, "w") as f:
|
||||||
f.write(
|
f.write(
|
||||||
f"""
|
templates["repo_with_remote"][configtype].format(
|
||||||
[[trees]]
|
root=target, remote=remote1, remotename="origin"
|
||||||
root = "{target}"
|
)
|
||||||
|
|
||||||
[[trees.repos]]
|
|
||||||
name = "test"
|
|
||||||
|
|
||||||
[[trees.repos.remotes]]
|
|
||||||
name = "origin"
|
|
||||||
url = "file://{remote1}"
|
|
||||||
type = "file"
|
|
||||||
"""
|
|
||||||
)
|
)
|
||||||
|
|
||||||
cmd = grm(["repos", "sync", "--config", config.name])
|
cmd = grm(["repos", "sync", "--config", config.name])
|
||||||
@@ -405,18 +439,9 @@ def test_repos_sync_normal_change_remote_url():
|
|||||||
|
|
||||||
with open(config.name, "w") as f:
|
with open(config.name, "w") as f:
|
||||||
f.write(
|
f.write(
|
||||||
f"""
|
templates["repo_with_remote"][configtype].format(
|
||||||
[[trees]]
|
root=target, remote=remote2, remotename="origin"
|
||||||
root = "{target}"
|
)
|
||||||
|
|
||||||
[[trees.repos]]
|
|
||||||
name = "test"
|
|
||||||
|
|
||||||
[[trees.repos.remotes]]
|
|
||||||
name = "origin"
|
|
||||||
url = "file://{remote2}"
|
|
||||||
type = "file"
|
|
||||||
"""
|
|
||||||
)
|
)
|
||||||
|
|
||||||
cmd = grm(["repos", "sync", "--config", config.name])
|
cmd = grm(["repos", "sync", "--config", config.name])
|
||||||
@@ -429,25 +454,17 @@ def test_repos_sync_normal_change_remote_url():
|
|||||||
assert urls[0] == f"file://{remote2}"
|
assert urls[0] == f"file://{remote2}"
|
||||||
|
|
||||||
|
|
||||||
def test_repos_sync_normal_change_remote_name():
|
@pytest.mark.parametrize("configtype", ["toml", "yaml"])
|
||||||
|
def test_repos_sync_normal_change_remote_name(configtype):
|
||||||
with tempfile.TemporaryDirectory() as target:
|
with tempfile.TemporaryDirectory() as target:
|
||||||
with TempGitFileRemote() as (remote1, remote1_head_commit_sha):
|
with TempGitFileRemote() as (remote1, remote1_head_commit_sha):
|
||||||
with TempGitFileRemote() as (remote2, remote2_head_commit_sha):
|
with TempGitFileRemote() as (remote2, remote2_head_commit_sha):
|
||||||
with tempfile.NamedTemporaryFile() as config:
|
with tempfile.NamedTemporaryFile() as config:
|
||||||
with open(config.name, "w") as f:
|
with open(config.name, "w") as f:
|
||||||
f.write(
|
f.write(
|
||||||
f"""
|
templates["repo_with_remote"][configtype].format(
|
||||||
[[trees]]
|
root=target, remote=remote1, remotename="origin"
|
||||||
root = "{target}"
|
)
|
||||||
|
|
||||||
[[trees.repos]]
|
|
||||||
name = "test"
|
|
||||||
|
|
||||||
[[trees.repos.remotes]]
|
|
||||||
name = "origin"
|
|
||||||
url = "file://{remote1}"
|
|
||||||
type = "file"
|
|
||||||
"""
|
|
||||||
)
|
)
|
||||||
|
|
||||||
cmd = grm(["repos", "sync", "--config", config.name])
|
cmd = grm(["repos", "sync", "--config", config.name])
|
||||||
@@ -465,18 +482,9 @@ def test_repos_sync_normal_change_remote_name():
|
|||||||
|
|
||||||
with open(config.name, "w") as f:
|
with open(config.name, "w") as f:
|
||||||
f.write(
|
f.write(
|
||||||
f"""
|
templates["repo_with_remote"][configtype].format(
|
||||||
[[trees]]
|
root=target, remote=remote1, remotename="origin2"
|
||||||
root = "{target}"
|
)
|
||||||
|
|
||||||
[[trees.repos]]
|
|
||||||
name = "test"
|
|
||||||
|
|
||||||
[[trees.repos.remotes]]
|
|
||||||
name = "origin2"
|
|
||||||
url = "file://{remote1}"
|
|
||||||
type = "file"
|
|
||||||
"""
|
|
||||||
)
|
)
|
||||||
|
|
||||||
cmd = grm(["repos", "sync", "--config", config.name])
|
cmd = grm(["repos", "sync", "--config", config.name])
|
||||||
@@ -492,25 +500,16 @@ def test_repos_sync_normal_change_remote_name():
|
|||||||
assert urls[0] == f"file://{remote1}"
|
assert urls[0] == f"file://{remote1}"
|
||||||
|
|
||||||
|
|
||||||
def test_repos_sync_worktree_clone():
|
@pytest.mark.parametrize("configtype", ["toml", "yaml"])
|
||||||
|
def test_repos_sync_worktree_clone(configtype):
|
||||||
with tempfile.TemporaryDirectory() as target:
|
with tempfile.TemporaryDirectory() as target:
|
||||||
with TempGitFileRemote() as (remote, head_commit_sha):
|
with TempGitFileRemote() as (remote, head_commit_sha):
|
||||||
with tempfile.NamedTemporaryFile() as config:
|
with tempfile.NamedTemporaryFile() as config:
|
||||||
with open(config.name, "w") as f:
|
with open(config.name, "w") as f:
|
||||||
f.write(
|
f.write(
|
||||||
f"""
|
templates["worktree_repo_with_remote"][configtype].format(
|
||||||
[[trees]]
|
root=target, remote=remote, remotename="origin"
|
||||||
root = "{target}"
|
)
|
||||||
|
|
||||||
[[trees.repos]]
|
|
||||||
name = "test"
|
|
||||||
worktree_setup = true
|
|
||||||
|
|
||||||
[[trees.repos.remotes]]
|
|
||||||
name = "origin"
|
|
||||||
url = "file://{remote}"
|
|
||||||
type = "file"
|
|
||||||
"""
|
|
||||||
)
|
)
|
||||||
|
|
||||||
cmd = grm(["repos", "sync", "--config", config.name])
|
cmd = grm(["repos", "sync", "--config", config.name])
|
||||||
@@ -530,19 +529,13 @@ def test_repos_sync_worktree_clone():
|
|||||||
assert str(repo.head.commit) == head_commit_sha
|
assert str(repo.head.commit) == head_commit_sha
|
||||||
|
|
||||||
|
|
||||||
def test_repos_sync_worktree_init():
|
@pytest.mark.parametrize("configtype", ["toml", "yaml"])
|
||||||
|
def test_repos_sync_worktree_init(configtype):
|
||||||
with tempfile.TemporaryDirectory() as target:
|
with tempfile.TemporaryDirectory() as target:
|
||||||
with tempfile.NamedTemporaryFile() as config:
|
with tempfile.NamedTemporaryFile() as config:
|
||||||
with open(config.name, "w") as f:
|
with open(config.name, "w") as f:
|
||||||
f.write(
|
f.write(
|
||||||
f"""
|
templates["worktree_repo_simple"][configtype].format(root=target)
|
||||||
[[trees]]
|
|
||||||
root = "{target}"
|
|
||||||
|
|
||||||
[[trees.repos]]
|
|
||||||
name = "test"
|
|
||||||
worktree_setup = true
|
|
||||||
"""
|
|
||||||
)
|
)
|
||||||
|
|
||||||
cmd = grm(["repos", "sync", "--config", config.name])
|
cmd = grm(["repos", "sync", "--config", config.name])
|
||||||
@@ -559,43 +552,42 @@ def test_repos_sync_worktree_init():
|
|||||||
assert not repo.head.is_valid()
|
assert not repo.head.is_valid()
|
||||||
|
|
||||||
|
|
||||||
def test_repos_sync_invalid_toml():
|
@pytest.mark.parametrize("configtype", ["toml", "yaml"])
|
||||||
|
def test_repos_sync_invalid_syntax(configtype):
|
||||||
with tempfile.NamedTemporaryFile() as config:
|
with tempfile.NamedTemporaryFile() as config:
|
||||||
with open(config.name, "w") as f:
|
with open(config.name, "w") as f:
|
||||||
f.write(
|
if configtype == "toml":
|
||||||
f"""
|
f.write(
|
||||||
[[trees]]
|
f"""
|
||||||
root = invalid as there are no quotes ;)
|
[[trees]]
|
||||||
"""
|
root = invalid as there are no quotes ;)
|
||||||
)
|
"""
|
||||||
|
)
|
||||||
|
elif configtype == "yaml":
|
||||||
|
f.write(
|
||||||
|
f"""
|
||||||
|
trees:
|
||||||
|
wrong:
|
||||||
|
indentation:
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
raise NotImplementedError()
|
||||||
cmd = grm(["repos", "sync", "--config", config.name])
|
cmd = grm(["repos", "sync", "--config", config.name])
|
||||||
assert cmd.returncode != 0
|
assert cmd.returncode != 0
|
||||||
|
|
||||||
|
|
||||||
def test_repos_sync_unchanged():
|
@pytest.mark.parametrize("configtype", ["toml", "yaml"])
|
||||||
|
def test_repos_sync_unchanged(configtype):
|
||||||
with tempfile.TemporaryDirectory() as target:
|
with tempfile.TemporaryDirectory() as target:
|
||||||
with TempGitFileRemote() as (remote1, remote1_head_commit_sha):
|
with TempGitFileRemote() as (remote1, remote1_head_commit_sha):
|
||||||
with TempGitFileRemote() as (remote2, remote2_head_commit_sha):
|
with TempGitFileRemote() as (remote2, remote2_head_commit_sha):
|
||||||
with tempfile.NamedTemporaryFile() as config:
|
with tempfile.NamedTemporaryFile() as config:
|
||||||
with open(config.name, "w") as f:
|
with open(config.name, "w") as f:
|
||||||
f.write(
|
f.write(
|
||||||
f"""
|
templates["repo_with_two_remotes"][configtype].format(
|
||||||
[[trees]]
|
root=target, remote1=remote1, remote2=remote2
|
||||||
root = "{target}"
|
)
|
||||||
|
|
||||||
[[trees.repos]]
|
|
||||||
name = "test"
|
|
||||||
|
|
||||||
[[trees.repos.remotes]]
|
|
||||||
name = "origin"
|
|
||||||
url = "file://{remote1}"
|
|
||||||
type = "file"
|
|
||||||
|
|
||||||
[[trees.repos.remotes]]
|
|
||||||
name = "origin2"
|
|
||||||
url = "file://{remote2}"
|
|
||||||
type = "file"
|
|
||||||
"""
|
|
||||||
)
|
)
|
||||||
|
|
||||||
cmd = grm(["repos", "sync", "--config", config.name])
|
cmd = grm(["repos", "sync", "--config", config.name])
|
||||||
@@ -609,25 +601,17 @@ def test_repos_sync_unchanged():
|
|||||||
assert before == after
|
assert before == after
|
||||||
|
|
||||||
|
|
||||||
def test_repos_sync_normal_change_to_worktree():
|
@pytest.mark.parametrize("configtype", ["toml", "yaml"])
|
||||||
|
def test_repos_sync_normal_change_to_worktree(configtype):
|
||||||
with tempfile.TemporaryDirectory() as target:
|
with tempfile.TemporaryDirectory() as target:
|
||||||
with TempGitFileRemote() as (remote1, remote1_head_commit_sha):
|
with TempGitFileRemote() as (remote1, remote1_head_commit_sha):
|
||||||
with TempGitFileRemote() as (remote2, remote2_head_commit_sha):
|
with TempGitFileRemote() as (remote2, remote2_head_commit_sha):
|
||||||
with tempfile.NamedTemporaryFile() as config:
|
with tempfile.NamedTemporaryFile() as config:
|
||||||
with open(config.name, "w") as f:
|
with open(config.name, "w") as f:
|
||||||
f.write(
|
f.write(
|
||||||
f"""
|
templates["repo_with_remote"][configtype].format(
|
||||||
[[trees]]
|
root=target, remote=remote1, remotename="origin"
|
||||||
root = "{target}"
|
)
|
||||||
|
|
||||||
[[trees.repos]]
|
|
||||||
name = "test"
|
|
||||||
|
|
||||||
[[trees.repos.remotes]]
|
|
||||||
name = "origin"
|
|
||||||
url = "file://{remote1}"
|
|
||||||
type = "file"
|
|
||||||
"""
|
|
||||||
)
|
)
|
||||||
|
|
||||||
cmd = grm(["repos", "sync", "--config", config.name])
|
cmd = grm(["repos", "sync", "--config", config.name])
|
||||||
@@ -637,19 +621,9 @@ def test_repos_sync_normal_change_to_worktree():
|
|||||||
|
|
||||||
with open(config.name, "w") as f:
|
with open(config.name, "w") as f:
|
||||||
f.write(
|
f.write(
|
||||||
f"""
|
templates["worktree_repo_with_remote"][configtype].format(
|
||||||
[[trees]]
|
root=target, remote=remote1, remotename="origin"
|
||||||
root = "{target}"
|
)
|
||||||
|
|
||||||
[[trees.repos]]
|
|
||||||
name = "test"
|
|
||||||
worktree_setup = true
|
|
||||||
|
|
||||||
[[trees.repos.remotes]]
|
|
||||||
name = "origin"
|
|
||||||
url = "file://{remote1}"
|
|
||||||
type = "file"
|
|
||||||
"""
|
|
||||||
)
|
)
|
||||||
|
|
||||||
cmd = grm(["repos", "sync", "--config", config.name])
|
cmd = grm(["repos", "sync", "--config", config.name])
|
||||||
@@ -658,26 +632,17 @@ def test_repos_sync_normal_change_to_worktree():
|
|||||||
assert "not using a worktree setup" in cmd.stderr
|
assert "not using a worktree setup" in cmd.stderr
|
||||||
|
|
||||||
|
|
||||||
def test_repos_sync_worktree_change_to_normal():
|
@pytest.mark.parametrize("configtype", ["toml", "yaml"])
|
||||||
|
def test_repos_sync_worktree_change_to_normal(configtype):
|
||||||
with tempfile.TemporaryDirectory() as target:
|
with tempfile.TemporaryDirectory() as target:
|
||||||
with TempGitFileRemote() as (remote1, remote1_head_commit_sha):
|
with TempGitFileRemote() as (remote1, remote1_head_commit_sha):
|
||||||
with TempGitFileRemote() as (remote2, remote2_head_commit_sha):
|
with TempGitFileRemote() as (remote2, remote2_head_commit_sha):
|
||||||
with tempfile.NamedTemporaryFile() as config:
|
with tempfile.NamedTemporaryFile() as config:
|
||||||
with open(config.name, "w") as f:
|
with open(config.name, "w") as f:
|
||||||
f.write(
|
f.write(
|
||||||
f"""
|
templates["worktree_repo_with_remote"][configtype].format(
|
||||||
[[trees]]
|
root=target, remote=remote1, remotename="origin"
|
||||||
root = "{target}"
|
)
|
||||||
|
|
||||||
[[trees.repos]]
|
|
||||||
name = "test"
|
|
||||||
worktree_setup = true
|
|
||||||
|
|
||||||
[[trees.repos.remotes]]
|
|
||||||
name = "origin"
|
|
||||||
url = "file://{remote1}"
|
|
||||||
type = "file"
|
|
||||||
"""
|
|
||||||
)
|
)
|
||||||
|
|
||||||
cmd = grm(["repos", "sync", "--config", config.name])
|
cmd = grm(["repos", "sync", "--config", config.name])
|
||||||
@@ -687,18 +652,9 @@ def test_repos_sync_worktree_change_to_normal():
|
|||||||
|
|
||||||
with open(config.name, "w") as f:
|
with open(config.name, "w") as f:
|
||||||
f.write(
|
f.write(
|
||||||
f"""
|
templates["repo_with_remote"][configtype].format(
|
||||||
[[trees]]
|
root=target, remote=remote1, remotename="origin"
|
||||||
root = "{target}"
|
)
|
||||||
|
|
||||||
[[trees.repos]]
|
|
||||||
name = "test"
|
|
||||||
|
|
||||||
[[trees.repos.remotes]]
|
|
||||||
name = "origin"
|
|
||||||
url = "file://{remote1}"
|
|
||||||
type = "file"
|
|
||||||
"""
|
|
||||||
)
|
)
|
||||||
|
|
||||||
cmd = grm(["repos", "sync", "--config", config.name])
|
cmd = grm(["repos", "sync", "--config", config.name])
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
from helpers import *
|
from helpers import *
|
||||||
|
|
||||||
|
import re
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
import git
|
import git
|
||||||
|
|
||||||
@@ -51,7 +53,9 @@ def test_worktree_fetch():
|
|||||||
|
|
||||||
@pytest.mark.parametrize("rebase", [True, False])
|
@pytest.mark.parametrize("rebase", [True, False])
|
||||||
@pytest.mark.parametrize("ffable", [True, False])
|
@pytest.mark.parametrize("ffable", [True, False])
|
||||||
def test_worktree_pull(rebase, ffable):
|
@pytest.mark.parametrize("has_changes", [True, False])
|
||||||
|
@pytest.mark.parametrize("stash", [True, False])
|
||||||
|
def test_worktree_pull(rebase, ffable, has_changes, stash):
|
||||||
with TempGitRepositoryWorktree() as (base_dir, root_commit):
|
with TempGitRepositoryWorktree() as (base_dir, root_commit):
|
||||||
with TempGitFileRemote() as (remote_path, _remote_sha):
|
with TempGitFileRemote() as (remote_path, _remote_sha):
|
||||||
shell(
|
shell(
|
||||||
@@ -94,51 +98,79 @@ def test_worktree_pull(rebase, ffable):
|
|||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if has_changes:
|
||||||
|
shell(
|
||||||
|
f"""
|
||||||
|
cd {base_dir}/master
|
||||||
|
echo change >> root-commit-in-worktree-1
|
||||||
|
echo uncommitedchange > uncommitedchange
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
args = ["wt", "pull"]
|
args = ["wt", "pull"]
|
||||||
if rebase:
|
if rebase:
|
||||||
args += ["--rebase"]
|
args += ["--rebase"]
|
||||||
|
if stash:
|
||||||
|
args += ["--stash"]
|
||||||
cmd = grm(args, cwd=base_dir)
|
cmd = grm(args, cwd=base_dir)
|
||||||
assert cmd.returncode == 0
|
if has_changes and not stash:
|
||||||
|
assert cmd.returncode != 0
|
||||||
assert repo.commit("upstream/master").hexsha == remote_commit
|
assert re.match(r".*master.*contains changes.*", cmd.stderr)
|
||||||
assert repo.commit("origin/master").hexsha == root_commit
|
|
||||||
assert (
|
|
||||||
repo.commit("master").hexsha != repo.commit("origin/master").hexsha
|
|
||||||
)
|
|
||||||
|
|
||||||
if not rebase:
|
|
||||||
if ffable:
|
|
||||||
assert (
|
|
||||||
repo.commit("master").hexsha
|
|
||||||
!= repo.commit("origin/master").hexsha
|
|
||||||
)
|
|
||||||
assert (
|
|
||||||
repo.commit("master").hexsha
|
|
||||||
== repo.commit("upstream/master").hexsha
|
|
||||||
)
|
|
||||||
assert repo.commit("upstream/master").hexsha == remote_commit
|
|
||||||
else:
|
|
||||||
assert "cannot be fast forwarded" in cmd.stderr
|
|
||||||
assert (
|
|
||||||
repo.commit("master").hexsha
|
|
||||||
!= repo.commit("origin/master").hexsha
|
|
||||||
)
|
|
||||||
assert repo.commit("master").hexsha != remote_commit
|
|
||||||
assert repo.commit("upstream/master").hexsha == remote_commit
|
|
||||||
else:
|
else:
|
||||||
if ffable:
|
assert repo.commit("upstream/master").hexsha == remote_commit
|
||||||
assert (
|
assert repo.commit("origin/master").hexsha == root_commit
|
||||||
repo.commit("master").hexsha
|
assert (
|
||||||
!= repo.commit("origin/master").hexsha
|
repo.commit("master").hexsha
|
||||||
)
|
!= repo.commit("origin/master").hexsha
|
||||||
assert (
|
)
|
||||||
repo.commit("master").hexsha
|
if has_changes:
|
||||||
== repo.commit("upstream/master").hexsha
|
assert ["uncommitedchange"] == repo.untracked_files
|
||||||
)
|
assert repo.is_dirty()
|
||||||
assert repo.commit("upstream/master").hexsha == remote_commit
|
|
||||||
else:
|
else:
|
||||||
assert (
|
assert not repo.is_dirty()
|
||||||
repo.commit("master").message.strip()
|
|
||||||
== "local-commit-in-master"
|
if not rebase:
|
||||||
)
|
if ffable:
|
||||||
assert repo.commit("master~1").hexsha == remote_commit
|
assert cmd.returncode == 0
|
||||||
|
assert (
|
||||||
|
repo.commit("master").hexsha
|
||||||
|
!= repo.commit("origin/master").hexsha
|
||||||
|
)
|
||||||
|
assert (
|
||||||
|
repo.commit("master").hexsha
|
||||||
|
== repo.commit("upstream/master").hexsha
|
||||||
|
)
|
||||||
|
assert (
|
||||||
|
repo.commit("upstream/master").hexsha == remote_commit
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
assert cmd.returncode != 0
|
||||||
|
assert "cannot be fast forwarded" in cmd.stderr
|
||||||
|
assert (
|
||||||
|
repo.commit("master").hexsha
|
||||||
|
!= repo.commit("origin/master").hexsha
|
||||||
|
)
|
||||||
|
assert repo.commit("master").hexsha != remote_commit
|
||||||
|
assert (
|
||||||
|
repo.commit("upstream/master").hexsha == remote_commit
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
assert cmd.returncode == 0
|
||||||
|
if ffable:
|
||||||
|
assert (
|
||||||
|
repo.commit("master").hexsha
|
||||||
|
!= repo.commit("origin/master").hexsha
|
||||||
|
)
|
||||||
|
assert (
|
||||||
|
repo.commit("master").hexsha
|
||||||
|
== repo.commit("upstream/master").hexsha
|
||||||
|
)
|
||||||
|
assert (
|
||||||
|
repo.commit("upstream/master").hexsha == remote_commit
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
assert (
|
||||||
|
repo.commit("master").message.strip()
|
||||||
|
== "local-commit-in-master"
|
||||||
|
)
|
||||||
|
assert repo.commit("master~1").hexsha == remote_commit
|
||||||
|
|||||||
@@ -2,15 +2,18 @@
|
|||||||
|
|
||||||
from helpers import *
|
from helpers import *
|
||||||
|
|
||||||
import pytest
|
import re
|
||||||
|
|
||||||
|
import pytest
|
||||||
import git
|
import git
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("pull", [True, False])
|
@pytest.mark.parametrize("pull", [True, False])
|
||||||
@pytest.mark.parametrize("rebase", [True, False])
|
@pytest.mark.parametrize("rebase", [True, False])
|
||||||
@pytest.mark.parametrize("ffable", [True, False])
|
@pytest.mark.parametrize("ffable", [True, False])
|
||||||
def test_worktree_rebase(pull, rebase, ffable):
|
@pytest.mark.parametrize("has_changes", [True, False])
|
||||||
|
@pytest.mark.parametrize("stash", [True, False])
|
||||||
|
def test_worktree_rebase(pull, rebase, ffable, has_changes, stash):
|
||||||
with TempGitRepositoryWorktree() as (base_dir, _root_commit):
|
with TempGitRepositoryWorktree() as (base_dir, _root_commit):
|
||||||
with open(os.path.join(base_dir, "grm.toml"), "w") as f:
|
with open(os.path.join(base_dir, "grm.toml"), "w") as f:
|
||||||
f.write('persistent_branches = ["mybasebranch"]')
|
f.write('persistent_branches = ["mybasebranch"]')
|
||||||
@@ -83,6 +86,14 @@ def test_worktree_rebase(pull, rebase, ffable):
|
|||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if has_changes:
|
||||||
|
shell(
|
||||||
|
f"""
|
||||||
|
cd {base_dir}/myfeatbranch
|
||||||
|
echo uncommitedchange > uncommitedchange
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
grm(["wt", "delete", "--force", "tmp"], cwd=base_dir)
|
grm(["wt", "delete", "--force", "tmp"], cwd=base_dir)
|
||||||
|
|
||||||
repo = git.Repo(f"{base_dir}/.git-main-working-tree")
|
repo = git.Repo(f"{base_dir}/.git-main-working-tree")
|
||||||
@@ -133,17 +144,23 @@ def test_worktree_rebase(pull, rebase, ffable):
|
|||||||
args += ["--pull"]
|
args += ["--pull"]
|
||||||
if rebase:
|
if rebase:
|
||||||
args += ["--rebase"]
|
args += ["--rebase"]
|
||||||
|
if stash:
|
||||||
|
args += ["--stash"]
|
||||||
cmd = grm(args, cwd=base_dir)
|
cmd = grm(args, cwd=base_dir)
|
||||||
|
|
||||||
print(args)
|
|
||||||
if rebase and not pull:
|
if rebase and not pull:
|
||||||
assert cmd.returncode != 0
|
assert cmd.returncode != 0
|
||||||
assert len(cmd.stderr) != 0
|
assert len(cmd.stderr) != 0
|
||||||
|
elif has_changes and not stash:
|
||||||
|
assert cmd.returncode != 0
|
||||||
|
assert re.match(r".*myfeatbranch.*contains changes.*", cmd.stderr)
|
||||||
else:
|
else:
|
||||||
assert cmd.returncode == 0
|
|
||||||
repo = git.Repo(f"{base_dir}/myfeatbranch")
|
repo = git.Repo(f"{base_dir}/myfeatbranch")
|
||||||
|
if has_changes:
|
||||||
|
assert ["uncommitedchange"] == repo.untracked_files
|
||||||
if pull:
|
if pull:
|
||||||
if rebase:
|
if rebase:
|
||||||
|
assert cmd.returncode == 0
|
||||||
if ffable:
|
if ffable:
|
||||||
assert (
|
assert (
|
||||||
repo.commit("HEAD").message.strip()
|
repo.commit("HEAD").message.strip()
|
||||||
@@ -190,6 +207,7 @@ def test_worktree_rebase(pull, rebase, ffable):
|
|||||||
assert repo.commit("HEAD~6").message.strip() == "commit-root"
|
assert repo.commit("HEAD~6").message.strip() == "commit-root"
|
||||||
else:
|
else:
|
||||||
if ffable:
|
if ffable:
|
||||||
|
assert cmd.returncode == 0
|
||||||
assert (
|
assert (
|
||||||
repo.commit("HEAD").message.strip()
|
repo.commit("HEAD").message.strip()
|
||||||
== "commit-in-feat-remote"
|
== "commit-in-feat-remote"
|
||||||
@@ -208,6 +226,7 @@ def test_worktree_rebase(pull, rebase, ffable):
|
|||||||
)
|
)
|
||||||
assert repo.commit("HEAD~4").message.strip() == "commit-root"
|
assert repo.commit("HEAD~4").message.strip() == "commit-root"
|
||||||
else:
|
else:
|
||||||
|
assert cmd.returncode != 0
|
||||||
assert (
|
assert (
|
||||||
repo.commit("HEAD").message.strip()
|
repo.commit("HEAD").message.strip()
|
||||||
== "commit-in-feat-local-no-ff"
|
== "commit-in-feat-local-no-ff"
|
||||||
@@ -226,6 +245,7 @@ def test_worktree_rebase(pull, rebase, ffable):
|
|||||||
)
|
)
|
||||||
assert repo.commit("HEAD~4").message.strip() == "commit-root"
|
assert repo.commit("HEAD~4").message.strip() == "commit-root"
|
||||||
else:
|
else:
|
||||||
|
assert cmd.returncode == 0
|
||||||
if ffable:
|
if ffable:
|
||||||
assert repo.commit("HEAD").message.strip() == "commit-in-feat-local"
|
assert repo.commit("HEAD").message.strip() == "commit-in-feat-local"
|
||||||
assert (
|
assert (
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ source ./venv/bin/activate
|
|||||||
pip --disable-pip-version-check install -r ./requirements.txt
|
pip --disable-pip-version-check install -r ./requirements.txt
|
||||||
|
|
||||||
pip3 list --outdated --format=freeze | grep -v '^\-e' | cut -d = -f 1 | while read -r package ; do
|
pip3 list --outdated --format=freeze | grep -v '^\-e' | cut -d = -f 1 | while read -r package ; do
|
||||||
|
[[ "$package" == "pip" ]] && continue
|
||||||
|
[[ "$package" == "setuptools" ]] && continue
|
||||||
pip install --upgrade "${package}"
|
pip install --upgrade "${package}"
|
||||||
version="$(pip show "${package}" | grep '^Version' | cut -d ' ' -f 2)"
|
version="$(pip show "${package}" | grep '^Version' | cut -d ' ' -f 2)"
|
||||||
message="e2e_tests/pip: Update ${package} to ${version}"
|
message="e2e_tests/pip: Update ${package} to ${version}"
|
||||||
|
|||||||
16
example.config.yaml
Normal file
16
example.config.yaml
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
trees:
|
||||||
|
- root: "~/example-projects/"
|
||||||
|
repos:
|
||||||
|
- name: "git-repo-manager"
|
||||||
|
remotes:
|
||||||
|
- name: "origin"
|
||||||
|
url: "https://code.hkoerber.de/hannes/git-repo-manager.git"
|
||||||
|
type: "https"
|
||||||
|
- name: "github"
|
||||||
|
url: "https://github.com/hakoerber/git-repo-manager.git"
|
||||||
|
type: "https"
|
||||||
|
- name: "dotfiles"
|
||||||
|
remotes:
|
||||||
|
- name: "origin"
|
||||||
|
url: "https://github.com/hakoerber/dotfiles.git"
|
||||||
|
type: "https"
|
||||||
@@ -36,6 +36,10 @@ impl Config {
|
|||||||
Err(error) => Err(error.to_string()),
|
Err(error) => Err(error.to_string()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn as_yaml(&self) -> Result<String, String> {
|
||||||
|
serde_yaml::to_string(self).map_err(|e| e.to_string())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
@@ -62,12 +66,15 @@ pub fn read_config(path: &str) -> Result<Config, String> {
|
|||||||
|
|
||||||
let config: Config = match toml::from_str(&content) {
|
let config: Config = match toml::from_str(&content) {
|
||||||
Ok(c) => c,
|
Ok(c) => c,
|
||||||
Err(e) => {
|
Err(_) => match serde_yaml::from_str(&content) {
|
||||||
return Err(format!(
|
Ok(c) => c,
|
||||||
"Error parsing configuration file \"{}\": {}",
|
Err(e) => {
|
||||||
path, e
|
return Err(format!(
|
||||||
))
|
"Error parsing configuration file \"{}\": {}",
|
||||||
}
|
path, e
|
||||||
|
))
|
||||||
|
}
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(config)
|
Ok(config)
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ use clap::{AppSettings, Parser};
|
|||||||
author = clap::crate_authors!("\n"),
|
author = clap::crate_authors!("\n"),
|
||||||
about = clap::crate_description!(),
|
about = clap::crate_description!(),
|
||||||
long_version = clap::crate_version!(),
|
long_version = clap::crate_version!(),
|
||||||
setting = AppSettings::DeriveDisplayOrder,
|
global_setting(AppSettings::DeriveDisplayOrder),
|
||||||
setting = AppSettings::PropagateVersion,
|
propagate_version = true,
|
||||||
)]
|
)]
|
||||||
pub struct Opts {
|
pub struct Opts {
|
||||||
#[clap(subcommand)]
|
#[clap(subcommand)]
|
||||||
@@ -61,10 +61,25 @@ pub struct OptionalConfig {
|
|||||||
pub config: Option<String>,
|
pub config: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(clap::ArgEnum, Clone)]
|
||||||
|
pub enum ConfigFormat {
|
||||||
|
Yaml,
|
||||||
|
Toml,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Parser)]
|
#[derive(Parser)]
|
||||||
pub struct Find {
|
pub struct Find {
|
||||||
#[clap(help = "The path to search through")]
|
#[clap(help = "The path to search through")]
|
||||||
pub path: String,
|
pub path: String,
|
||||||
|
|
||||||
|
#[clap(
|
||||||
|
arg_enum,
|
||||||
|
short,
|
||||||
|
long,
|
||||||
|
help = "Format to produce",
|
||||||
|
default_value_t = ConfigFormat::Toml,
|
||||||
|
)]
|
||||||
|
pub format: ConfigFormat,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Parser)]
|
#[derive(Parser)]
|
||||||
@@ -132,6 +147,8 @@ pub struct WorktreeFetchArgs {}
|
|||||||
pub struct WorktreePullArgs {
|
pub struct WorktreePullArgs {
|
||||||
#[clap(long = "--rebase", help = "Perform a rebase instead of a fast-forward")]
|
#[clap(long = "--rebase", help = "Perform a rebase instead of a fast-forward")]
|
||||||
pub rebase: bool,
|
pub rebase: bool,
|
||||||
|
#[clap(long = "--stash", help = "Stash & unstash changes before & after pull")]
|
||||||
|
pub stash: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Parser)]
|
#[derive(Parser)]
|
||||||
@@ -140,6 +157,11 @@ pub struct WorktreeRebaseArgs {
|
|||||||
pub pull: bool,
|
pub pull: bool,
|
||||||
#[clap(long = "--rebase", help = "Perform a rebase when doing a pull")]
|
#[clap(long = "--rebase", help = "Perform a rebase when doing a pull")]
|
||||||
pub rebase: bool,
|
pub rebase: bool,
|
||||||
|
#[clap(
|
||||||
|
long = "--stash",
|
||||||
|
help = "Stash & unstash changes before & after rebase"
|
||||||
|
)]
|
||||||
|
pub stash: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse() -> Opts {
|
pub fn parse() -> Opts {
|
||||||
|
|||||||
@@ -119,15 +119,34 @@ fn main() {
|
|||||||
} else {
|
} else {
|
||||||
let config = trees.to_config();
|
let config = trees.to_config();
|
||||||
|
|
||||||
let toml = match config.as_toml() {
|
match find.format {
|
||||||
Ok(toml) => toml,
|
cmd::ConfigFormat::Toml => {
|
||||||
Err(error) => {
|
let toml = match config.as_toml() {
|
||||||
print_error(&format!("Failed converting config to TOML: {}", &error));
|
Ok(toml) => toml,
|
||||||
process::exit(1);
|
Err(error) => {
|
||||||
|
print_error(&format!(
|
||||||
|
"Failed converting config to TOML: {}",
|
||||||
|
&error
|
||||||
|
));
|
||||||
|
process::exit(1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
print!("{}", toml);
|
||||||
}
|
}
|
||||||
};
|
cmd::ConfigFormat::Yaml => {
|
||||||
|
let yaml = match config.as_yaml() {
|
||||||
print!("{}", toml);
|
Ok(yaml) => yaml,
|
||||||
|
Err(error) => {
|
||||||
|
print_error(&format!(
|
||||||
|
"Failed converting config to YAML: {}",
|
||||||
|
&error
|
||||||
|
));
|
||||||
|
process::exit(1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
print!("{}", yaml);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for warning in warnings {
|
for warning in warnings {
|
||||||
print_warning(&warning);
|
print_warning(&warning);
|
||||||
@@ -350,26 +369,27 @@ fn main() {
|
|||||||
process::exit(1);
|
process::exit(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let mut failures = false;
|
||||||
for worktree in repo.get_worktrees().unwrap_or_else(|error| {
|
for worktree in repo.get_worktrees().unwrap_or_else(|error| {
|
||||||
print_error(&format!("Error getting worktrees: {}", error));
|
print_error(&format!("Error getting worktrees: {}", error));
|
||||||
process::exit(1);
|
process::exit(1);
|
||||||
}) {
|
}) {
|
||||||
if let Some(warning) =
|
if let Some(warning) = worktree
|
||||||
worktree
|
.forward_branch(args.rebase, args.stash)
|
||||||
.forward_branch(args.rebase)
|
.unwrap_or_else(|error| {
|
||||||
.unwrap_or_else(|error| {
|
print_error(&format!("Error updating worktree branch: {}", error));
|
||||||
print_error(&format!(
|
process::exit(1);
|
||||||
"Error updating worktree branch: {}",
|
})
|
||||||
error
|
|
||||||
));
|
|
||||||
process::exit(1);
|
|
||||||
})
|
|
||||||
{
|
{
|
||||||
print_warning(&format!("{}: {}", worktree.name(), warning));
|
print_warning(&format!("{}: {}", worktree.name(), warning));
|
||||||
|
failures = true;
|
||||||
} else {
|
} else {
|
||||||
print_success(&format!("{}: Done", worktree.name()));
|
print_success(&format!("{}: Done", worktree.name()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if failures {
|
||||||
|
process::exit(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
cmd::WorktreeAction::Rebase(args) => {
|
cmd::WorktreeAction::Rebase(args) => {
|
||||||
if args.rebase && !args.pull {
|
if args.rebase && !args.pull {
|
||||||
@@ -406,10 +426,12 @@ fn main() {
|
|||||||
process::exit(1);
|
process::exit(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let mut failures = false;
|
||||||
|
|
||||||
for worktree in &worktrees {
|
for worktree in &worktrees {
|
||||||
if args.pull {
|
if args.pull {
|
||||||
if let Some(warning) = worktree
|
if let Some(warning) = worktree
|
||||||
.forward_branch(args.rebase)
|
.forward_branch(args.rebase, args.stash)
|
||||||
.unwrap_or_else(|error| {
|
.unwrap_or_else(|error| {
|
||||||
print_error(&format!(
|
print_error(&format!(
|
||||||
"Error updating worktree branch: {}",
|
"Error updating worktree branch: {}",
|
||||||
@@ -418,28 +440,29 @@ fn main() {
|
|||||||
process::exit(1);
|
process::exit(1);
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
|
failures = true;
|
||||||
print_warning(&format!("{}: {}", worktree.name(), warning));
|
print_warning(&format!("{}: {}", worktree.name(), warning));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for worktree in &worktrees {
|
for worktree in &worktrees {
|
||||||
if let Some(warning) =
|
if let Some(warning) = worktree
|
||||||
worktree
|
.rebase_onto_default(&config, args.stash)
|
||||||
.rebase_onto_default(&config)
|
.unwrap_or_else(|error| {
|
||||||
.unwrap_or_else(|error| {
|
print_error(&format!("Error rebasing worktree branch: {}", error));
|
||||||
print_error(&format!(
|
process::exit(1);
|
||||||
"Error rebasing worktree branch: {}",
|
})
|
||||||
error
|
|
||||||
));
|
|
||||||
process::exit(1);
|
|
||||||
})
|
|
||||||
{
|
{
|
||||||
|
failures = true;
|
||||||
print_warning(&format!("{}: {}", worktree.name(), warning));
|
print_warning(&format!("{}: {}", worktree.name(), warning));
|
||||||
} else {
|
} else {
|
||||||
print_success(&format!("{}: Done", worktree.name()));
|
print_success(&format!("{}: Done", worktree.name()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if failures {
|
||||||
|
process::exit(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
88
src/repo.rs
88
src/repo.rs
@@ -181,17 +181,30 @@ impl Worktree {
|
|||||||
&self.name
|
&self.name
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn forward_branch(&self, rebase: bool) -> Result<Option<String>, String> {
|
pub fn forward_branch(&self, rebase: bool, stash: bool) -> Result<Option<String>, String> {
|
||||||
let repo = Repo::open(Path::new(&self.name), false)
|
let repo = Repo::open(Path::new(&self.name), false)
|
||||||
.map_err(|error| format!("Error opening worktree: {}", error))?;
|
.map_err(|error| format!("Error opening worktree: {}", error))?;
|
||||||
|
|
||||||
if let Ok(remote_branch) = repo.find_local_branch(&self.name)?.upstream() {
|
if let Ok(remote_branch) = repo.find_local_branch(&self.name)?.upstream() {
|
||||||
let status = repo.status(false)?;
|
let status = repo.status(false)?;
|
||||||
|
let mut stashed_changes = false;
|
||||||
|
|
||||||
if !status.clean() {
|
if !status.clean() {
|
||||||
return Ok(Some(String::from("Worktree contains changes")));
|
if stash {
|
||||||
|
repo.stash()?;
|
||||||
|
stashed_changes = true;
|
||||||
|
} else {
|
||||||
|
return Ok(Some(String::from("Worktree contains changes")));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let unstash = || -> Result<(), String> {
|
||||||
|
if stashed_changes {
|
||||||
|
repo.stash_pop()?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
};
|
||||||
|
|
||||||
let remote_annotated_commit = repo
|
let remote_annotated_commit = repo
|
||||||
.0
|
.0
|
||||||
.find_annotated_commit(remote_branch.commit()?.id().0)
|
.find_annotated_commit(remote_branch.commit()?.id().0)
|
||||||
@@ -231,6 +244,7 @@ impl Worktree {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
rebase.abort().map_err(convert_libgit2_error)?;
|
rebase.abort().map_err(convert_libgit2_error)?;
|
||||||
|
unstash()?;
|
||||||
return Err(convert_libgit2_error(error));
|
return Err(convert_libgit2_error(error));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -243,9 +257,11 @@ impl Worktree {
|
|||||||
.map_err(convert_libgit2_error)?;
|
.map_err(convert_libgit2_error)?;
|
||||||
|
|
||||||
if analysis.is_up_to_date() {
|
if analysis.is_up_to_date() {
|
||||||
|
unstash()?;
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
}
|
}
|
||||||
if !analysis.is_fast_forward() {
|
if !analysis.is_fast_forward() {
|
||||||
|
unstash()?;
|
||||||
return Ok(Some(String::from("Worktree cannot be fast forwarded")));
|
return Ok(Some(String::from("Worktree cannot be fast forwarded")));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -257,15 +273,18 @@ impl Worktree {
|
|||||||
)
|
)
|
||||||
.map_err(convert_libgit2_error)?;
|
.map_err(convert_libgit2_error)?;
|
||||||
}
|
}
|
||||||
|
unstash()?;
|
||||||
} else {
|
} else {
|
||||||
return Ok(Some(String::from("No remote branch to rebase onto")));
|
return Ok(Some(String::from("No remote branch to rebase onto")));
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn rebase_onto_default(
|
pub fn rebase_onto_default(
|
||||||
&self,
|
&self,
|
||||||
config: &Option<WorktreeRootConfig>,
|
config: &Option<WorktreeRootConfig>,
|
||||||
|
stash: bool,
|
||||||
) -> Result<Option<String>, String> {
|
) -> Result<Option<String>, String> {
|
||||||
let repo = Repo::open(Path::new(&self.name), false)
|
let repo = Repo::open(Path::new(&self.name), false)
|
||||||
.map_err(|error| format!("Error opening worktree: {}", error))?;
|
.map_err(|error| format!("Error opening worktree: {}", error))?;
|
||||||
@@ -291,6 +310,25 @@ impl Worktree {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let status = repo.status(false)?;
|
||||||
|
let mut stashed_changes = false;
|
||||||
|
|
||||||
|
if !status.clean() {
|
||||||
|
if stash {
|
||||||
|
repo.stash()?;
|
||||||
|
stashed_changes = true;
|
||||||
|
} else {
|
||||||
|
return Ok(Some(String::from("Worktree contains changes")));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let unstash = || -> Result<(), String> {
|
||||||
|
if stashed_changes {
|
||||||
|
repo.stash_pop()?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
};
|
||||||
|
|
||||||
let base_branch = repo.find_local_branch(&default_branch_name)?;
|
let base_branch = repo.find_local_branch(&default_branch_name)?;
|
||||||
let base_annotated_commit = repo
|
let base_annotated_commit = repo
|
||||||
.0
|
.0
|
||||||
@@ -330,11 +368,13 @@ impl Worktree {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
rebase.abort().map_err(convert_libgit2_error)?;
|
rebase.abort().map_err(convert_libgit2_error)?;
|
||||||
|
unstash()?;
|
||||||
return Err(convert_libgit2_error(error));
|
return Err(convert_libgit2_error(error));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rebase.finish(None).map_err(convert_libgit2_error)?;
|
rebase.finish(None).map_err(convert_libgit2_error)?;
|
||||||
|
unstash()?;
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -456,6 +496,35 @@ impl Repo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn stash(&self) -> Result<(), String> {
|
||||||
|
let head_branch = self.head_branch()?;
|
||||||
|
let head = head_branch.commit()?;
|
||||||
|
let author = head.author();
|
||||||
|
|
||||||
|
// This is honestly quite horrible. The problem is that all stash operations expect a
|
||||||
|
// mutable reference (as they, well, mutate the repo after all). But we are heavily using
|
||||||
|
// immutable references a lot with this struct. I'm really not sure how to best solve this.
|
||||||
|
// Right now, we just open the repo AGAIN. It is safe, as we are only accessing the stash
|
||||||
|
// with the second reference, so there are no cross effects. But it just smells. Also,
|
||||||
|
// using `unwrap()` here as we are already sure that the repo is openable(?).
|
||||||
|
let mut repo = Repo::open(self.0.path(), false).unwrap();
|
||||||
|
repo.0
|
||||||
|
.stash_save2(&author, None, Some(git2::StashFlags::INCLUDE_UNTRACKED))
|
||||||
|
.map_err(convert_libgit2_error)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn stash_pop(&self) -> Result<(), String> {
|
||||||
|
let mut repo = Repo::open(self.0.path(), false).unwrap();
|
||||||
|
repo.0
|
||||||
|
.stash_pop(
|
||||||
|
0,
|
||||||
|
Some(git2::StashApplyOptions::new().reinstantiate_index()),
|
||||||
|
)
|
||||||
|
.map_err(convert_libgit2_error)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn rename_remote(&self, remote: &RemoteHandle, new_name: &str) -> Result<(), String> {
|
pub fn rename_remote(&self, remote: &RemoteHandle, new_name: &str) -> Result<(), String> {
|
||||||
let failed_refspecs = self
|
let failed_refspecs = self
|
||||||
.0
|
.0
|
||||||
@@ -1253,6 +1322,10 @@ impl Commit<'_> {
|
|||||||
pub fn id(&self) -> Oid {
|
pub fn id(&self) -> Oid {
|
||||||
Oid(self.0.id())
|
Oid(self.0.id())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(self) fn author(&self) -> git2::Signature {
|
||||||
|
self.0.author()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Branch<'a> {
|
impl<'a> Branch<'a> {
|
||||||
@@ -1323,9 +1396,7 @@ fn get_remote_callbacks() -> git2::RemoteCallbacks<'static> {
|
|||||||
Some(username) => username,
|
Some(username) => username,
|
||||||
None => panic!("Could not get username. This is a bug"),
|
None => panic!("Could not get username. This is a bug"),
|
||||||
};
|
};
|
||||||
git2::Cred::ssh_key_from_agent(username).or_else(|_| {
|
git2::Cred::ssh_key_from_agent(username)
|
||||||
git2::Cred::ssh_key(username, None, &crate::env_home().join(".ssh/id_rsa"), None)
|
|
||||||
})
|
|
||||||
});
|
});
|
||||||
|
|
||||||
callbacks
|
callbacks
|
||||||
@@ -1436,8 +1507,11 @@ pub fn clone_repo(
|
|||||||
repo.rename_remote(&origin, &remote.name)?;
|
repo.rename_remote(&origin, &remote.name)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut active_branch = repo.head_branch()?;
|
// If there is no head_branch, we most likely cloned an empty repository and
|
||||||
active_branch.set_upstream(&remote.name, &active_branch.name()?)?;
|
// there is no point in setting any upstreams.
|
||||||
|
if let Ok(mut active_branch) = repo.head_branch() {
|
||||||
|
active_branch.set_upstream(&remote.name, &active_branch.name()?)?;
|
||||||
|
};
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user