├── script └── install.sh ├── doc ├── img1.jpg └── img2.jpg ├── install.sh ├── src ├── cgit.hpp ├── utils.hpp ├── main.cpp ├── string.hpp ├── utils.cpp └── cgit.cpp ├── CMakeLists.txt ├── .gitignore ├── LICENSE └── README.md /script/install.sh: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /doc/img1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/killf/cgit/HEAD/doc/img1.jpg -------------------------------------------------------------------------------- /doc/img2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/killf/cgit/HEAD/doc/img2.jpg -------------------------------------------------------------------------------- /install.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | mkdir cgit/build && cd cgit/build && cmake .. 3 | make -j8 && sudo make install -------------------------------------------------------------------------------- /src/cgit.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CGIT_H 2 | #define CGIT_H 3 | 4 | #include 5 | #include 6 | 7 | #include "string.hpp" 8 | 9 | namespace cgit { 10 | string get_git_file(bool q = true); 11 | 12 | int cgit_clone(std::vector &argv); 13 | } 14 | 15 | #endif //CGIT_H 16 | -------------------------------------------------------------------------------- /src/utils.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CGIT_UTILS_HPP 2 | #define CGIT_UTILS_HPP 3 | 4 | namespace cgit { 5 | const char *get_env(const char *name, const char *default_value); 6 | 7 | int exec(const string &file_name, char *const *arguments); 8 | 9 | int cd(const string &path); 10 | } 11 | #endif //CGIT_UTILS_HPP 12 | -------------------------------------------------------------------------------- /src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "string.hpp" 4 | #include "cgit.hpp" 5 | #include "utils.hpp" 6 | 7 | using namespace cgit; 8 | 9 | int main(int argc, char **argv) { 10 | std::vector args(argc); 11 | for (int i = 0; i < argc; i++) { 12 | args[i] = argv[i]; 13 | } 14 | 15 | if (argc > 2 && args[1] == "clone") return cgit_clone(args); 16 | else return exec(get_git_file(false), argv); 17 | } 18 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.14) 2 | project(cgit CXX) 3 | 4 | set(CMAKE_CXX_STANDARD 11) 5 | 6 | IF (WIN32) 7 | set(CMAKE_CXX_FLAGS_RELEASE "/MT ${CMAKE_CXX_FLAGS}") 8 | set(CMAKE_CXX_FLAGS_DEBUG "/MTd ${CMAKE_CXX_FLAGS}") 9 | ELSE () 10 | set(CMAKE_CXX_FLAGS "-static ${CMAKE_CXX_FLAGS}") 11 | ENDIF () 12 | add_executable(cgit src/main.cpp src/cgit.cpp src/string.hpp src/utils.hpp src/utils.cpp) 13 | 14 | message(STATUS ${CMAKE_INSTALL_BINDIR}) 15 | 16 | install(TARGETS cgit RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Object files 5 | *.o 6 | *.ko 7 | *.obj 8 | *.elf 9 | 10 | # Linker output 11 | *.ilk 12 | *.map 13 | *.exp 14 | 15 | # Precompiled Headers 16 | *.gch 17 | *.pch 18 | 19 | # Libraries 20 | *.lib 21 | *.a 22 | *.la 23 | *.lo 24 | 25 | # Shared objects (inc. Windows DLLs) 26 | *.dll 27 | *.so 28 | *.so.* 29 | *.dylib 30 | 31 | # Executables 32 | *.exe 33 | *.out 34 | *.app 35 | *.i*86 36 | *.x86_64 37 | *.hex 38 | 39 | # Debug files 40 | *.dSYM/ 41 | *.su 42 | *.idb 43 | *.pdb 44 | 45 | # Kernel Module Compile Results 46 | *.mod* 47 | *.cmd 48 | .tmp_versions/ 49 | modules.order 50 | Module.symvers 51 | Mkfile.old 52 | dkms.conf 53 | 54 | .idea/ 55 | cmake-build-debug/ -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 killf 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/string.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CGIT_STRING_HPP 2 | #define CGIT_STRING_HPP 3 | 4 | #include 5 | 6 | namespace cgit { 7 | class string : public std::string { 8 | public: 9 | string() : std::string() {} 10 | 11 | string(const string &s) : std::string(s) {} 12 | 13 | string(const char *s) : std::string(s) {} 14 | 15 | string(const std::string &s) : std::string(s) {} 16 | 17 | string operator()(int n, int m) { 18 | return substr(n, m); 19 | } 20 | 21 | bool startsWith(const string &prefix) { 22 | if (this->size() < prefix.size())return false; 23 | 24 | const char *p1 = this->c_str(); 25 | const char *p2 = prefix.c_str(); 26 | 27 | while (*p2 != 0) { 28 | if (*p2++ != *p1++)return false; 29 | } 30 | 31 | return true; 32 | } 33 | 34 | bool endswith(const string &suffix) { 35 | if (this->size() < suffix.size())return false; 36 | 37 | const char *s = this->c_str() + (this->size() - suffix.size()); 38 | return suffix == s; 39 | } 40 | }; 41 | } 42 | 43 | #endif //CGIT_STRING_HPP 44 | -------------------------------------------------------------------------------- /src/utils.cpp: -------------------------------------------------------------------------------- 1 | #ifndef CGIT_UTILS_HPP 2 | #define CGIT_UTILS_HPP 3 | 4 | #ifdef WIN32 5 | #include 6 | #include 7 | #else 8 | #include 9 | #endif 10 | 11 | #include "string.hpp" 12 | 13 | namespace cgit { 14 | #ifdef WIN32 15 | const char *get_env(const char *name, const char *default_value) { 16 | char *file = nullptr; 17 | size_t len; 18 | errno_t err = _dupenv_s(&file, &len, name); 19 | return err == 0 && file != nullptr ? file : default_value; 20 | } 21 | 22 | int exec(const string &file_name, char *const *arguments) { 23 | return _execv(file_name.c_str(), arguments); 24 | } 25 | 26 | int cd(const string &path) { 27 | return _chdir(path.c_str()); 28 | } 29 | #else 30 | const char *get_env(const char *name, const char *default_value) { 31 | char *file = getenv(name); 32 | return file ? file : default_value; 33 | } 34 | 35 | int exec(const string &file_name, char *const* arguments){ 36 | return execv(file_name.c_str(), arguments); 37 | } 38 | 39 | int cd(const string &path) { 40 | return chdir(path.c_str()); 41 | } 42 | #endif 43 | } 44 | #endif //CGIT_UTILS_HPP 45 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # cgit 2 | 3 | > cgit是一个github快速下载器,使用国内镜像,clone速度可达10M/s。 4 | 5 | ### 一、安装方法 6 | 7 | 目前,已提供了Ubuntu、Mac、Window的预编译程序,如果使用的是其他系统,可以采用源码编译安装。 8 | 9 | **linux下安装** 10 | ```shell script 11 | sudo wget http://cgit.killf.info/cgit_linux_latest -O /usr/local/bin/cgit && sudo chmod 755 /usr/local/bin/cgit 12 | ``` 13 | 14 | **mac下安装** 15 | ```shell script 16 | sudo wget http://cgit.killf.info/cgit_mac_latest -O /usr/local/bin/cgit && sudo chmod 755 /usr/local/bin/cgit 17 | ``` 18 | 19 | **arm下安装** 20 | ```shell script 21 | sudo wget http://cgit.killf.info/cgit_arm_latest -O /usr/local/bin/cgit && sudo chmod 755 /usr/local/bin/cgit 22 | ``` 23 | 24 | **window下安装** 25 | 26 | 点击[下载](http://cgit.killf.info/cgit.exe)链接,将程序放到你喜欢的目录下,然后将该路径配置`PATH`变量下 27 | 28 | **编译安装** 29 | ```shell script 30 | git clone https://github.com/killf/cgit.git && sudo ./cgit/install.sh 31 | ``` 32 | 33 | ### 二、使用方法 34 | 35 | cgit运行时与需要使用git,因此需要先安装git。 36 | linux平台下GIT的默认地址为`/usr/bin/git`,window平台下GIT的默认地址为`C:\\Program Files\\Git\\bin\\git.exe`, 37 | 如果需要使用其他路径的git,可配置环境变量`GIT`,如: 38 | 39 | ```shell 40 | export GIT=/usr/bin/git 41 | ``` 42 | 43 | 也可以通过设置环境变量`CGIT_MIRROR`来修改默认的镜像地址,如: 44 | 45 | ```shell 46 | export CGIT_MIRROR=https://hub.fastgit.org 47 | ``` 48 | 49 | cgit的使用方法git与一样,事实上内部使用的也是git,使用时只需将命令替换成cgit即可,如下: 50 | 51 | ``` 52 | cgit clone https://github.com/killf/cgit.git 53 | ``` 54 | 55 | ### 三、下载速度 56 | 57 | ![](doc/img1.jpg) 58 | 59 | ![](doc/img2.jpg) 60 | -------------------------------------------------------------------------------- /src/cgit.cpp: -------------------------------------------------------------------------------- 1 | #include "cgit.hpp" 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "utils.hpp" 8 | 9 | #ifdef WIN32 10 | #define DEFAULT_GIT_FILE "C:\\Program Files\\Git\\bin\\git.exe" 11 | #else 12 | #define DEFAULT_GIT_FILE "/usr/bin/git" 13 | #endif 14 | 15 | #define DEFAULT_GITHUB_URL "https://github.com/" 16 | #define DEFAULT_MIRROR_URL "https://github.com.cnpmjs.org/" 17 | 18 | namespace cgit { 19 | using namespace std; 20 | 21 | static string create_cmd(std::vector &args) { 22 | std::ostringstream ss; 23 | for (const auto &s:args) { 24 | #ifdef WIN32 25 | ss << s << " "; 26 | #else 27 | ss << "\"" << s << "\" "; 28 | #endif 29 | } 30 | return ss.str(); 31 | } 32 | 33 | string get_git_file(bool q) { 34 | auto git = get_env("GIT", DEFAULT_GIT_FILE); 35 | if (git == nullptr) { 36 | printf("please set the environment variable `GIT`."); 37 | exit(-1); 38 | } 39 | 40 | string git_str(git); 41 | if (q && git_str[0] != '"') git_str = '"' + git_str + '"'; 42 | 43 | return git_str; 44 | } 45 | 46 | string get_cgit_mirror() { 47 | string url = get_env("CGIT_MIRROR", DEFAULT_MIRROR_URL); 48 | if (url.length() > 0 && !url.endswith("/"))url += '/'; 49 | return url; 50 | } 51 | 52 | int cgit_clone(vector &args) { 53 | // 0.get env for GIT and CGIT_MIRROR 54 | string git_file = get_git_file(); 55 | string mirror_url = get_cgit_mirror(); 56 | 57 | // 1.git clone https://github.com.cnpmjs.org/killf/cgit.git 58 | string old_url, new_url, folder_name; 59 | for (size_t i = 2; i < args.size(); i++) { 60 | if (args[i].startsWith(DEFAULT_GITHUB_URL)) { 61 | old_url = args[i]; 62 | new_url = args[i].replace(0, strlen(DEFAULT_GITHUB_URL), mirror_url.c_str()); 63 | 64 | auto index = old_url.find_last_of('/'); 65 | if (index != std::string::npos) { 66 | folder_name = old_url.substr(index + 1); 67 | if (folder_name.endswith(".git")) { 68 | folder_name = folder_name.substr(0, folder_name.size() - 4); 69 | } 70 | } 71 | } 72 | } 73 | 74 | args[0] = git_file.c_str(); 75 | auto cmd1 = create_cmd(args); 76 | auto err = system(cmd1.c_str()); 77 | if (err != 0 || new_url.empty() || folder_name.empty())return err; 78 | 79 | // 2.cd cgit 80 | err = cd(folder_name); 81 | if (err != 0)return err; 82 | 83 | // 3.git remote set-url origin https://github.com/killf/cgit.git 84 | auto cmd3 = "git remote set-url origin \"" + old_url + "\""; 85 | return system(cmd3.c_str()); 86 | } 87 | } 88 | --------------------------------------------------------------------------------