Git从入门到精通
Git简介
git是一个开源的分布式版本控制系统,用于多人协同开发项目的代码管理工具。
1、代码管理工具的用途
- 防止代码丢失,做备份
- 项目的版本管理和控制,可以通过设置节点进行跳转
- 建立各自的开发环境分支,互不影响,方便合并
- 在多终端开发时,方便代码的相互传输
2、git的特点
- git是开源的,多在*nix下使用,可以管理各种文件
- git是分布式的项目管理工具(svn是集中式的)
- git数据管理更多样化,分享速度快,数据安全
- git 拥有更好的分支支持,方便多人协调
Git 配置
配置命令: git config
- 设置系统配置,git config --system [选项]
- 配置文件位置:
/etc/gitconfig
- 配置文件位置:
- 当前用户配置, git config --global [选项]
- 配置文件位置:
~/.gitconfig
- 配置文件位置:
- 当前仓库配置,配置当前项目: git config [选项]
- 配置文件位置:
.git/config
- 配置文件位置:
在 Windows 系统上,Git 会找寻系统配置,只不过看当初 Git 装在什么目录,就以此作为根目录来定位。
配置信息
# 设置用户名 $ git config --global user.name Never # 设置用户邮箱 $ git config --global user.email 1786088***@qq.com # 配置编译器为pycharm $ git config --global core.editor pycharm # 差异分析工具 $ git config --global merge.tool vimdiff
查看配置信息
$ git config --list use.name=Never user.name=Never user.email=1786088***@qq.com core.repositoryformatversion=0 core.filemode=true core.bare=false core.logallrefupdates=true core.editor=pycharm
基本概念
基本概念
- 工作区(workspace),本地硬盘存放代码的地方
- 暂存区(index),临时存放用户的改动,一般存放在 .git/index 目录中
- 版本库(Repository),又叫做本地仓库,这里面存放 提交的所有版本数据,其中HEAD指向最新放入仓库的版本
- 远程仓库(Remote),托管代码的服务器
注意:只有版本库的内容才能和其他远程仓库交互。
基本命令
*1、初始化仓库 git init
在当前目录下生成一个.git文件夹,用于对该目录进行git管理,
Git还为我们自动创建第一个分支 master ,以及指向master的一个指针叫 HEAD 。
*2、查看仓库当前的状态,显示有变更的文件 git status
*3、将指定文件添加到暂存区 git add [files..]
- e.g. 将指定目录添加到暂存区 git add [dir]
- e.g. 将所有文件(不包含隐藏文件)添加到暂存区 git add .
说明:只有纳入暂存区的文件,git才会对齐进行跟踪,便于进行版本控制
*5、将暂存区所有文件同步到版本库 git commit -m "提交说明"
e.g. 将暂存区指定文件同步到本地仓库 git commit [file] -m [message]
*6、将版本库连接远程仓库 git remote add origin https:xxxxxxxxx.git
*7、将本地的master分支推送给远程仓库 git push -u origin master
这个时候会让我们输入github账号和密码。
从远程拉取仓库: git clone <repo.git> <directory>
- repo:git仓库地址
- directory:[可选] 本地目录
9、比较本地工作区和暂存区 file文件差异 git diff [file]
比较两个分支的差异: git diff <source_branch> <target_branch>
11、移动或者删除文件
git mv [file] [path]
git rm [files]
注意: 这两个操作会修改工作区内容,同时将操作记录提交到暂存区。
删除暂存区文件 git rm --cached [file]
12、忽略文件
有时候我们不想把某些文件纳入版本控制,可以通过在项目文件夹下定义.gitignore文件,在每行指定一个文件夹名,被指定的文件夹在提交的时候会被忽略,忽略命令.
- file 表示忽略file文件
- *.py 表示忽略所有 .py 结尾的文件
- !lib.py 表示lib.py除外
- build/ 表示忽略 build/目录下的所有文件,过滤整个build文件夹
- /build 表示忽略的文件在 build目录下,而子目录中的文件不忽略
在git不能提交空文件夹,如果你想让他出现,需要在里面放一些东西,比如:.gitkeep
修订提交
如果我们提交过后发现有个文件改错了,或者只是想修改提交说明,这时可以对相应文件做出修改,将修改过的文件通过"git add"添加到暂存区,然后执行以下命令 git commit --amend
撤销提交(commit)
原理就是放弃工作区和index的改动,同时HEAD指针指向前一个commit对象 git reset --hard HEAD~1
好了,如果作为新手只想要入门学会基本操作,那么学到这里已经足够了,后面为git更加细致的讲解,涉及版本控制
版本控制
1、撤销更新 git reset --hard
- 退回到上一个commit节点 git reset --hard HEAD~1退回到指定的commit_id节点 git reset --hard [commit_id]
- 注意 : 1表示回退1个版本,依次类推。当版本回退之后工作区会自动和当前commit版本保持一致,日志也会删除
- 取消提交到版本库,移回到暂存区 git reset HEAD <file>
3. 查看所有操作记录 git reflog
注意:最上面的为最新记录,可以利用commit_id去往任何操作位置
保存工作区
1. 保存工作区内容 git stash save [message]
说明: 将工作区未提交的修改封存,让工作区回到修改前的状态
2. 查看工作区列表 git stash list
说明:最新保存的工作区在最上面
3. 应用某个工作区 git stash apply [stash@{n}]
4. 删除工作区
- 删除某一个工作区 git stash drop [stash@{n}]
- 删除所有保存的工作区 git stash clear
分支管理
分支即每个人在原有代码(分支)的基础上建立自己的工作环境,单独开发,互不干扰。完成开发工作后再进行分支统一合并。
1、查看所有分支 git branch
说明: 没有参数时,git会列出本地分支,前面带 * 的分支表示当前工作分支
git branch -a 查看本地和远程分支
git branch -r 只查看远端分支
2、在本地新建一个分支 git branch branch_name
说明: 基于a分支创建b分支,此时b分支会拥有a分支全部内容。在创建b分支时最好保持a分支"干净"状态。
3、切换分支 git checkout branch_name
步骤2,3可以同时操作,即创建并切换分支 git checkout -b branch_name
但我们切换到新的分支时,原来master分支的内容都会不见,切换回master分支时,他们又会重新出现
4、将新的分支上传到github git push origin branchName
5、合并branch_name分支到当前分支 git merge branch_name
冲突问题是合并分支过程中最为棘手的问题,当分支合并时,原分支和合并分支修改了同一个文件就会产生冲突,
这时候就需要你手动修改这些文件来合并冲突,改完后可以用git add告诉git文件冲突已经解决。
$ git status -s UU runoob.php $ git add runoob.php $ git status -s M runoob.php $ git commit [master 88afe0e] Merge branch 'change_site'
6、删除分支
- 删除本地分支 git branch -d branch_name
- 删除没有被合并的分支 git branch -D branch_name
8、删除远端分支: git push origin :branchName (分支名前的冒号代表删除)
远程仓库
拉取
git clone
克隆命令,克隆远程仓库用于创建一个本地仓库的完整副本,包括所有分支、标签、历史记录,如果仓库已经存在,git clone 不会更新现有仓库的。
通常用于开始一个新的项目,或者当你需要一个项目的完整副本时。
git clone [-b 分支名] https://github.com/xxxxxxxxx.git [本地文件夹]
git fetch
获取命令,用于从远程仓库获取数据,但不会自动合并这些变化到本地
git fetch origin
你可以使用 git fetch 来查看远程分支的最新状态,或者在合并之前检查远程分支的变更。
git fetch 后,你需要手动执行 git merge 或 git rebase 来更新你的本地分支
获取远程所有分支: git fetch --all
git pull
拉取命令,它首先从远程仓库获取最新数据,然后将远程分支的变更合并到当前分支(实际上是 git fetch 后跟 git merge 的快捷方式)
git pull 通常用于更新你的本地仓库,使其与远程仓库保持同步。如果有冲突,git pull 会在合并过程中提示你解决。
git pull [origin master]
简而言之,git clone 用于初始化本地仓库,git fetch 用于获取远程仓库的最新状态而不自动合并,而 git pull 是获取最新状态并自动尝试合并到当前分支的快捷命令。
推送
本地仓库推送到远程
1、添加远程仓库 git remote add [shortname] [url]
本地 Git 仓库和 GitHub 仓库之间的传输是通过SSH加密的,你需要生成SSH Key,然后添加到github服务器的公钥中。
2、将本地分支推送给远程仓库 git push [-u] [仓库名] [分支名]
一般形式为:git push [-u] origin master ,将master分支推送给origin主机远程仓库
-u选项会将你所推送的分支与远程分支进行关联,以后推送只需使用git push就会自动将修改推送到 origin 仓库的 master 分支
3、查看当前的远程仓库 git remote [-v]
执行时加上 -v 参数,你还可以看到每个别名的实际链接地址。
删除对远程仓库的跟踪(不会影响实际的远程仓库) git remote rm [仓库名]
删除远程分支
- 查看所有分支 git branch -a
- 删除远程分支 git push 远程仓库名 -d 分支名
标签
如果你达到一个重要的阶段,并希望永远记住那个特别的commit,你可以使用 git tag 给它打上标签。保存当时的工作状态,一般用于版本的迭代。
创建标签 git tag -a [tag_name] [commit_id] -m [message]
说明: commit_id不写则默认标签表示最新的commit_id位置,message标签注释。
e.g. 在最新的commit处添加标签v1.0 git tag -a v1.0 -m '版本1'
查看标签
查看标签列表 git tag
查看标签详细信息 git show [tag_name]
去往某个标签节点 git reset --hard [tag]
删除标签 git tag -d [tag]
查看提交历史
Git 提交历史一般常用两个命令:
- 查看历史提交记录 git log
- 以列表形式查看指定文件的历史修改记录 git blame <file>
查看commit 日志记录 git log [--oneline] [--graph] [--reverse] [--author]
- --oneline:查看历史记录的纯净版本
- --graph:以拓扑图查看历史中什么时候出现了分支、合并
- --reverse:逆向显示
- --author:查看提交的作者
- --name-status:查看哪些文件改变了
签出
如果版本库中已经存在文件f4.txt,在本地工作区中对f4修改了,如果想撤销本地修改可以使用checkout,签出覆盖本地
切换分支,用分支的内容替换本地: git checkout branch
汇总显示工作区、暂存区与HEAD的差异 git checkout [HEAD]
暂存区中filename文件来覆盖工作区中的filename文件 git checkout -- filename
用暂存区的所有文件直接覆盖本地文件 git checkout .
此命令会使用 HEAD 中的最新内容替换掉你的本地文件。已添加到暂存区的改动以及新文件都不会受到影响。
假如你想丢弃你在本地的所有改动与提交,可以到服务器上获取最新的版本历史,并将你本地主分支指向它:
git fetch origin
git reset --hard origin/master
使用gitee
代码托管平台除了github还有gitlab、gitee、coding。那一个本地仓库如何关联两个托管平台呢?使用多个远程库时,我们要注意,git给远程仓库起的默认名称是origin,如果有多个远程库,我们需要用不同的名称来标识不同的远程库。
1、我们首先要先删除已关联的名为origin
的远程库:
$ git remote rm origin
2、然后,先关联GitHub的远程库:
$ git remote add github git@github.com:xxx/xxx.git
注意,远程库的名称叫github,不叫origin了。
3、接着,再关联Gitee的远程库:
$ git remote add gitee git@gitee.com:xxx/xxx.git
4、现在,我们用git remote -v查看远程库信息,可以看到两个远程库:
$ git remote -v gitee git@gitee.com:xxx/xxx.git (fetch) gitee git@gitee.com:xxx/xxx.git (push) github git@github.com:xxx/xxx.git (fetch) github git@github.com:xxx/xxx.git (push)
5、推送
如果要推送到GitHub,使用命令: git push github master
如果要推送到Gitee,使用命令: git push gitee master
这样一来,我们的本地库就可以同时与多个远程库互相同步:
git子模块管理
在Git中,你可以通过子模块(submodules)或者仓库的嵌套来管理一个Git项目中的多个Git仓库。这两种方法都允许你在一个Git项目中包含其他Git仓库,但它们有不同的用途和工作方式。
1 子模块(Submodules)
子模块是Git项目中包含其他Git仓库的一种方法。它允许你将一个独立的Git仓库嵌套在另一个Git仓库中,并且可以保持这些嵌套仓库的独立性。这对于管理依赖项或将其他项目作为子模块包含在主项目中非常有用。
以下是如何使用子模块的一些步骤:
a. 在主项目中添加子模块:
git submodule add <repository_url> <path_to_submodule_directory>
b. 初始化子模块:
git submodule init
这将初始化子模块并下载其内容。
c. 更新子模块:
git submodule update
这将获取子模块的最新版本。
d. 提交主项目的更新:
git commit -m "Add and update submodule"
如果子模块内容发生了更改,父模块也要随之更改。我们应该先进入到子模块中进行git add和git commit以及git push,然后父目录也需要进行git add和git commit以及git push相似的操作,以记录主项目对子模块的新引用。
cd path/to/submodule git add . git commit -m "Update submodule" git push
再更新父目录
cd .. git add path/to/submodule git commit -m "Update submodule reference" git push
如果克隆主项目时同时克隆子模块
git clone --recursive <主项目的远程仓库URL>
如果你已经克隆了主项目,但忘记使用 --recursive 选项,你可以在主项目的根目录中运行以下命令来初始化和更新子模块: git submodule update --init --recursive
2 仓库嵌套(Nested Repositories)
你也可以简单地将一个Git仓库放到另一个Git仓库中的子目录中,然后在主项目中管理这些子仓库。这种方法通常更简单,但子仓库的历史记录将与主项目一起管理,可能不适用于所有情况。
以下是如何将一个Git仓库嵌套在另一个Git仓库中的一些步骤:
a. 在主项目中创建一个目录,用于存放子仓库。
b. 将子仓库克隆到该目录中。
c. 在主项目中进行修改并提交,包括子仓库目录。
d. 子仓库的更改将与主项目一起提交。
选择子模块还是仓库嵌套取决于你的需求。子模块提供更强大的独立性,但需要更多的管理工作。仓库嵌套更简单,但会将子仓库的历史记录与主项目混合在一起。根据你的项目需求和工作流程,选择适合你的方法。
仓库迁移
要将一个仓库的所有分支复制到另一个仓库,可以按照以下步骤进行操作。
1、克隆源仓库
git clone --mirror https://github.com/LXP-Never/AEC_DeepModel.git
cd AEC_DeepModel
2、添加目标仓库作为新的远程仓库
git remote add gitee https://gitee.com/LXP-Never/AEC_DeepModel.git
3、将所有分支和标签推送到目标仓库
git push --all --tags gitee
这样会将原始仓库的所有分支都推送到目标仓库。
注意事项:
- 如果目标仓库已经存在,你可能需要在
git push
命令中使用--force
选项以覆盖目标仓库中的内容。请小心使用此选项,确保你知道它的影响。 - 如果目标仓库是空的,你也可以考虑直接使用 git push --mirror gitee 命令,这将复制原始仓库的所有分支和标签到目标仓库,包括提交历史。
参考
【git】git官方
【博客园--张果】一个小时学会Git
【博客园】解决github下载速度慢问题
【GitDoc】git - 简明指南