文章目录
- git - study
- 概述
- 可以用 git gui工具来添加快捷命令工具
- 如果要在提交日志中搜索,可以用gitk的view编辑功能
- 实验环境
- 直接用git自带环境进行git操作的好处
- 查看git所有配置
- 配置全局数据
- 配置项目专用的数据
- 查询配置数据的原始值
- 配置git使用的文本编辑器
- 获取某个git命令的帮助
- git基本操作
- 需要确认自己要操作的项目的主分支的名称
- 初始化git项目
- 克隆仓库
- 查看项目文件的状态
- 设置要被git操作忽略的文件
- 文件变化的比较
- 图形化比较
- git diff 方法
- 提交文件
- 查看log
- 远程仓库
- 推送代码
- 建立分支
- 切换到指定的分支
- 推送分支
- 查看所有分支
- 自动add所有后提交
- 查看分支 - 命令
- 查看分支还是用gitk方便
- 切换分支时,如果还没有提交
- 合并分支
- 删除分支
- 远程分支
- 删除远程分支
- rebase
- 远端的git库搭建
- 打标签
- 查看标签
- 推送本地所有标签到远端
- 查看远端标签
- 备注
- 推送所有
- 用git自带工具的感受
- git命令行的好处
- 让git命令行显示中文
- 导出git库的全部日志到文件
- 删除工程中未归档的文件
- 让任何实验都git归档
- 更新本地已经迁出的git库
- 统计工程总提交次数
- 将linux路径显示为windows路径
- 查看git库的建立时间
- END
git - study
概述
progit 这本书是官方的,权威。
以下内容都是对这本书的读书笔记和实验的体会。
这本官方的书,前半部分说git命令具体怎么用,后半部分说github怎么用 + git高级和细节的操作。因为作者就是github的人。
能看完前半部分对自己有用的部分,就可以熟练用git命令来进行日常的git操作了。
对于危险的git操作(e.g. 删除本地分支,删除远程分支,删除tag, rebase, reset), 最好不要做。如果非要做的话,最好找个靠谱的GUI工具来弄。
只记录一些正常git操作中能用得到的,危险/高级的指令不学习。
只保证用git for win自带的工具能进行正常的git库操作就行, 以后只用官方的git工具。
像看日志这种操作用git自带的gitk命令来图形化查看日志。
日常操作也可以用git gui这个命令来用图形化的方式完成。
官方做的这2个工具git命令的封装比较好(一个用来提交,一个用来看日志),工具也比较轻量。
可以用 git gui工具来添加快捷命令工具
如果要在提交日志中搜索,可以用gitk的view编辑功能
实验环境
$git--versiongitversion2.48.1.windows.1直接用git自带环境进行git操作的好处
git bash + gitk + git gui
每一步都有明确的提示,如果操作一步后,漏了啥操作,可以明确的知道。
现在的git前端gui工具,都只是封装了一部分的git命令,所有还是用原生的git命令操作最直接。
将常用的/或者说全部能用到的git命令记录下来,该进行什么git命令操作,如果忘了,就查一下自己的笔记,很快就能熟练的使用git命令行了。
如果有些操作(e.g. 查看git历史和版本)用命令行不直观,这时就可以用gitk来辅助。
查看git所有配置
git config --list --show-origin配置全局数据
git config --global xx 向git的全局配置文件中写入内容
$ git config --global user.name "John Doe" $ git config --global user.email johndoe@example.comGit 会使用它找到的每一个变量的最后一个配置, 一般来说,全局git配置数据在前面,项目本身的git配置数据在后面。
配置项目专用的数据
git config xx 向项目本身的配置文件中写入内容
$ git config user.name "John Doe" $ git config user.email johndoe@example.com查询配置数据的原始值
$ git config --show-origin rerere.autoUpdate file:/home/johndoe/.gitconfig false配置git使用的文本编辑器
git config --global core.editor xxe.g.
$ git config --global core.editor "'C:\Users\chenx\AppData\Local\Programs\Microsoft VS Code\Code.exe' "获取某个git命令的帮助
$ git <verb> --helpe.g.
$ git config --help一般来说,会弹出一个本地网页或者远程网页来显示请求的git 命令的帮助。
git基本操作
需要确认自己要操作的项目的主分支的名称
主分支的名称都是默认的,不是main, 就是master, 和库建立时的选项(主分支默认名称)有关系。
初始化git项目
命令行用 git bash
cd ./my_project git init这个目录现在就可以作为一个git仓库了。
增加一个test1.c, LICENSE
向git项目添加文件
git add *.c git add LICENSE提交
git commit -m 'initial project version'克隆仓库
在一个非git项目的目录(该目录没有.git目录), 可以克隆远程仓库
git clone <远程仓库的url> [迁出到本地的目录名称] git clone https://github.com/libgit2/libgit2 mylibgit查看项目文件的状态
git status如果项目提交后,未变动,就显示未工作树是干净的
如果项目中新增了文件,就会显示出该文件,不用我们自己去找哪个文件该被添加。
如果项目中的文件被修改了,也会显示出来。
如果工作目录中的文件被删掉了,也会被列出来。
如果嫌弃列出的文件信息太复杂,可以用短格式。
git status -s段格式的标记含义如下
- ’ ’ = unmodified
- M= modified
- T= file type changed (regular file, symbolic link or submodule)
- A= added
- D= deleted
- R= renamed
- C= copied (if config option status.renames is set to “copies”)
- U= updated but unmerged
X Y Meaning ------------------------------------------------- [AMD] not updated M [ MTD] updated in index T [ MTD] type changed in index A [ MTD] added to index D deleted from index R [ MTD] renamed in index C [ MTD] copied in index [MTARC] index and work tree matches [ MTARC] M work tree changed since index [ MTARC] T type changed in work tree since index [ MTARC] D deleted in work tree R renamed in work tree C copied in work tree ------------------------------------------------- D D unmerged, both deleted A U unmerged, added by us U D unmerged, deleted by them U A unmerged, added by them D U unmerged, deleted by us A A unmerged, both added U U unmerged, both modified ------------------------------------------------- ? ? untracked ! ! ignored -------------------------------------------------设置要被git操作忽略的文件
直接新建或编辑 .gitignore 文件,一般就是根目录下有一个.gitignore文件。但是项目中的每个目录都可以有.gitignore.
.gitignore的例子 : https://github.com/github/gitignore , 这个例子中有各种语言的.gitignore。
这些 .gitignore的例子很详细(e.g c, c++, VS), 需要时可以参考。
文件变化的比较
git diff图形化比较
git difftool --tool-help默认是用 vimdiff 来比较,通过帮助,可以看到,居然支持bc4.
先设置git的difftool git config --global diff.tool bc4 git config --global difftool.prompt false git config --global difftool.bc4.path "C:\Program Files\Beyond Compare 5\BCompare.exe"C:\Users\me\.gitconfig如果是自己打开文件来看,BC4那里是有path的转义符号(\)的
[diff]tool=bc4[difftool"bc4"]cmd=\"C:\\Program Files\\Beyond Compare5\\BCompare.exe\"\"$LOCAL\"\"$REMOTE\"如果是用命令来看, 必须不报错,并显示bc4的配置
gitconfig--global--listgit diff 方法
curid- 4b7774b30e681e56987b52d05632464c4e882ffd previd- cd73b23142c5f9939970d41af04bf760ee74c733gitdifftool<ID1><ID2>gitdifftool cd73b23142c5f9939970d41af04bf760ee74c733 4b7774b30e681e56987b52d05632464c4e882ffd在gitk中找到要比较的2个ID, 然后就可以用bc4比较了。
提交文件
gitaddtest1.cgitcommit-m'test commit modify file'# 如果提交时,不加 -m 'xx', 就会弹出VSCODE, 让填写提交信息如果提交信息只有一行,用 -m比较方便。
如果有多行提交信息,在弹出的VSCODE中编辑多行信息,保存这个文件后,git就会自动提交。关掉保存的VSCODE就行了。
如果用 git status 看到的文件都是自己想要的文件,而不是垃圾文件或者不需要提交的文件。就可以全部自动add然后提交
如果用git status 看到了不该提交的文件,就先设置忽略文件,或者自己将不需要提交文件从资源管理器中删除,再提交
// 这个不好使,那一个一个添加也行gitcommit-a-m"v2"gitaddLICENSE file1.txt test1.c查看log
gitlog用git log 只能简单看一下,工程大了不现实。
gitk用gitk这个git自带的工具看,很方便清晰
远程仓库
如果有要迁出的远程仓库,就迁出到本地。
如果自己要做一个本地的仓库做实验,参考(git,gitea - tool - creat Gitea Empty Rep Dir).
现在自己做了一个实验仓库rep_my_git_study用于远程仓库的实验。
然后迁出到本地
gitclone http://localhost:3000/name/my_git_study.git my_git_study_gitea现在就可以做远程git库的实验了。
查看当前迁出工程的远程库
$gitremote-vorigin http://localhost:3000/name/my_git_study.git(fetch)origin http://localhost:3000/name/my_git_study.git(push)以前还特意去看当前目录的属性,看tortoisegit的git属性页,才知道这个库的git url是啥。
现在用 remote命令就可以很方便的知道当前库的git url.
现在对tortoisegit不感冒了,已经将tortoisegit卸载了。
推送代码
gitpush origin<分支名称>// origin 就是remote是看到的远程分支? // 如果不指定分支名称,就是当前分支如果是第一次克隆的库,如果项目的名字不在gitea远端的用户名列表内,至少要设置项目的git用户名称
否则认证失败。
gitconfig global user.name"name"建立分支
gitbranch<新分支名称># 从当前的Head上, 建立一个新分支切换到指定的分支
# 建立分支后,并不会自动切换到那个新分支# 如果向切到指定的分支,必须手工切换gitcheckout<已经存在的分支名称>gitswitch<已经存在的分支名称># 优先使用 git checkout改变HEAD的方法,只有切换到指定分支,才能够改变HEAD的指向。
推送分支
在本地开分支后,推送后,并不会自动推送到远端url.
需要显势推送分支到远端
gitpush<remote><branch>远端一般是origin,可以用下列命令查看远端的符号
如果分支已经推送过了,再重复推送,只是更新了状态,并不会有其他不良后果。
gitremote-v# 确定远端url符号是 origin列出本地分支名称
gitbranch-vgitpush origin<branch>查看远端的分支信息
gitbranch-r-vgitremote show origin查看所有分支
gitbranch-a-v如果远端没有本地的分支,就要将本地分支推到远端, 如果认证失败,需要配置项目的用户名称和email
用户名和email是远端配置好的,要配套。
如果是第一次推送,需要将远端网页开着
gitconfig user.name"name"gitconfig user.email"me@x.com"gitpush origin br-1再查看远端的分支信息,就有本地建立的分支了。
推送的时候,如果不指定分支,那就是推送到当前分支。
自动add所有后提交
# 如果用git status 看到的文件都是自己想要的,可以用下列命令自己添加全部文件后提交gitcommit-a-m'v3 - made a change'查看分支 - 命令
gitlog--oneline--decorate--graph--all查看分支还是用gitk方便
向看分支情况时,还是切到gitk, 然后选中所有分支选项。
切换分支时,如果还没有提交
$gitcheckout br-1 error: Yourlocalchanges to the following files would be overwritten by checkou t: file1.txt Please commit your changes or stash them before you switch branches. Aborting如果切换分支时,本地分支还没提交,会有提示。不会意外丢失文件修改内容。
用git命令操作还是很安全和透明的。
合并分支
# 先切回主分支(要接受其他分支内容合并的分支)gitcheckout master# 在合并之前,比较一下2个版本有啥区别?gitdiffbr-1gitdifftool br-1# 在主分支中,指定要合并过来的分支gitmerge hotfix# 合并分支后,合并的内容并不会自动出现在当前分支,需要重新迁出当前分支gitcheckout master如果合并出现冲突,可以使用图形化的工具来合并
# 设置合并工具为 Beyond Comparegitconfig--globalmerge.tool bc4gitconfig--globalmergetool.extMerge.cmd'bc4 "$BASE" "$LOCAL" "$REMOTE" "$MERGED"'gitconfig--globalmergetool.extMerge.trustExitCodefalsegitconfig--globaldiff.external extDiffgitmergetool<要合并的分支名称># 试过了不好使,提示没有东西要合并# 那么就用git merge br-xx 来合并好了# 果真不好使,还是用命令行来合并...## 估计BC4不可以作为合并工具删除分支
如果确定一个分支没用了(e.g. 只是一个实验分支,且实验结果已经合并到了主分支, 且这个实验分支以后再也没有人去用,留着也没有参考价值)
# 先回到主分支gitcheckout main# 再删除不要的其他分支# 如果删除其他分支时有报错,请将每个分支的内容都提交gitbranch-d<要删除的分支名称># 删除了本地分支后,远程还有这个分支# 如果该分支还没有合并到主分支,会提示还未合并,无法删除# 如果确认这个分支的工作都是白搭的,用下列命令强制删除gitbranch-D<要删除的分支名称># 删除分支这样的操作,还是挺危险的,如果不是刚需,还是留着分支。# 当然,开分支的时候,就要想清楚,是否真的要开分支# 用git branch -a -v 查看分支# 看到远端还有这个分支,只是本地已经没有这个分支了远程分支
从远端库拉取变化
gitfetch origin删除远程分支
删除远程分支是十分危险的操作, 万一有权连上远程库的人干坏事咋弄?
gitpush origin--delete<远程分支名称>gitpush origin--deletebr-1# 直接被删掉了,挺危险的...# 为了安全,不管是本地分支,还是远程分支,最好不要删除# 另外,远程库的备份看来是十分必要的# reflog的保存时限默认是90天, 万一管理员没有注意到误操作,只能从备份恢复# 虽然可以用本地reflog恢复,但是还是挺危险的,还是不要删除分支!!!。# 因为git操作是针对开源工程的,每个人都有权限做所有事,为了安全,备份确实是必要的。rebase
rebase比较危险,容易造成提交历史的混乱(弄丢提交者和细节提交的文件变化)和开发流程的混乱。
用merge可以完成所有的功能。
不要使用rebase(对于一般的git用户), 有分支合并的任务时,都用merge来做。
只有库的拥有者为了合并主线(版本)方便(众多贡献者协作完成了一个稳定的版本),才有可能用rebase来进行合并的偷懒。
远端的git库搭建
就用gitea命令行就行
如果自己要做一个本地的仓库做实验,参考(git,gitea - tool - creat Gitea Empty Rep Dir).
打标签
用gitk查看提交记录,找到自己要打标签的点的提交ID 9282cccb8a99591b3f1053819bfeb37cde29ff45
git tag -a v0.9.0 9282cccb8a99591b3f1053819bfeb37cde29ff45 -m “v0.9.0”
查看标签
gittag推送本地所有标签到远端
gitpush origin--tags# 推送时,要将gitea的远端管理网页打开,否则失败查看远端标签
gitls-remote--tagsorigin备注
如果只是初步的来用git命令行来干活,看官方书籍的前半部分就行。
有需要再在官方的书中找。
一次都看完,也消化不了,因为书中git操作的深度和广度都挺大的。有些场景,git新手用不到。
在官方书籍的最后,将大类的命令列出来,有快捷方式可以导航到大类命令去仔细看。
推送所有
时间久了,一个工程如果忘记了是否遗漏了要推送的内容,可以尝试全部推送一次。
推送前,先确认一下工程的用户名和email是否正确, 如果不正确,改过来。
chenx@ls3561 MINGW64 /d/my_dev/my_git_study_gitea(main)$gitconfig user.name name chenx@ls3561 MINGW64 /d/my_dev/my_git_study_gitea(main)$gitconfig user.name my_name chenx@ls3561 MINGW64 /d/my_dev/my_git_study_gitea(main)$gitconfig user.email me@x.com chenx@ls3561 MINGW64 /d/my_dev/my_git_study_gitea(main)$gitconfig user.email my_email@x.com chenx@ls3561 MINGW64 /d/my_dev/my_git_study_gitea(main)$查看要推送的url是否正确?如果不正确,改过来(适用于从第三方的git url克隆的库,但是想推送到自己的git库进行后续私有维护)
# 查看要推送的库gitremote-vorigin http://localhost:3000/name/my_git_study.git(fetch)origin http://localhost:3000/name/my_git_study.git(push)# 修改要推送的git urlgitremote set-url origin<新仓库地址.git>gitremote set-url origin http://localhost:3000/lostspeed/my_git_study.git需要打开git服务端的网页
再确认一下服务端的用户名和口令是否正确。
执行 b1_list_rep_user.bat
如果用户名不是自己要的,用a2_create_rep_user_pwd.bat改为自己中意的名字和email
如果用户名是自己要的,但是口令需要改一下,用b2_modify_rep_user_pwd.bat来改。
确认客户端要推送上来的库是否存在,如果不存在,需要自己新建的一个同名的库(适合于从第三方迁出,但是想推送到自己的私有库)。
# 如果第一次推送认证失败,再推送一次,在git服务端弹出的认证允许页面,点击允许,就可以推送成功了# 如果已经推送成功,再执行推送命令,也不会有不良影响,只是显示所有都更新了日期gitpush--allorigin&&gitpush--tagsorigin推送所有完成后,及时将git库管理网页, 客户端git bash窗口,gitea服务端的命令行都关掉。防止自己从其他小库操作时出意外。
因为每个小库的git url的端口都是3000.
用git自带工具的感受
还是官方出的工具NB, 简洁,方便,直观。
以前都在用第三方的git前端工具(e.g. tortoisegit), 如果对于git 新手,用第三方的git 前端,可以免去学习git命令,方便。
但是看git官方的书,里面开篇就提到“这将花费你生命中的几小时来学习git”, 说的很有道理,就几个小时的学习,就能掌握80%的git操作内容,已经足够日常使用git的场景了。如果遇到git操作的细节问题,再来看官方这本书。
现在用官方的git bash 命令行 + git gui + gitk的全家桶,感觉很好,再也不想去用第三方的git 前端的工具了。
如果不想输入命令行,可以自己做一些脚本,来执行自己常用的git命令。
git gui 本身也可以添加一些菜单命令,可以将自己常用的git命令添加为菜单,点击就能执行。
最后,如果真不想输入git命令,那么自己写个程序,封装git命令来干活,也行.
git命令行的好处
只要git命令没达到效果或语法出错,总是会有提示信息,告诉用户怎么做才能解决问题,这点特别好。
e.g. 计算机的win10重装了,git status 无法生效,就提示,需要将这个git库目录加入配置中,需要这个git库目录才行。
且给出了命令的格式。
让git命令行显示中文
默认安装完的git命令行中显示被操作的文件时,用\xxx来显示中文字符,看的不清晰。
$gitstatus On branch master Your branch is up todatewith'origin/master'.Changes not stagedforcommit:(use"git add <file>..."to update what will be committed)(use"git restore <file>..."to discard changesinworking directory)modified:"hardware/LS_openpnp_hardware/doc/\351\243\236\350\276\276\346\216\247\345\210\266\345\215\241\350\260\203\350\257\225\347\254\224\350\256\260.md"可以关闭git字符转义功能。
$gitconfig--globalcore.quotepathfalse此后,如果再用git操作中文文件,就是正常显示中文。
$gitstatus On branch master Your branch is up todatewith'origin/master'.Changes not stagedforcommit:(use"git add <file>..."to update what will be committed)(use"git restore <file>..."to discard changesinworking directory)modified: hardware/LS_openpnp_hardware/doc/飞达控制卡调试笔记.md //!!这里就是正常显示中文文件名 no changes added to commit(use"git add"and/or"git commit -a")导出git库的全部日志到文件
如果想在git软件外,查看全部的提交日志。
gitlog>d:\\my_tmp\\log.txt删除工程中未归档的文件
当工程完成时,或者想重新完整编译工程时,可能需要先清除工程中未归档的文件(e.g. IDE产生的临时文件,或者编译过程中产生的临时文件)
// 先看看, 是否可以全部清除gitstatus // 如果确认了, 未归档的文件都是临时的,可以全部清除的,就开始清除这些全部文件gitclean-f-d-x// 再看看,是否清干净了gitstatus让任何实验都git归档
有时做一个实验,不知道这个实验是否有用。如果最后归档或者丢弃时,也不知道自己到底做了啥?中间过程是否有收获?
可以从一开始做实验,就git本地归档,如果有价值,想归档到自己的远程服务器,再添加远程url即可。
# 开始任何实验前,都在新建的目录中,初始化一个空的git工程gitinit# 然后如果有了进度,就可以用Sourcetree进行git操作,将进度都在本地的这个git工程实现。# 不管这个实验有没有价值,中间过程都可以在本地归档记录。这样自己临时的想法或者已经做过的实验步骤,就不会被遗忘。# 如果这个实验真的值得保存,这时再添加远程提交的url不迟。// 用gitea在远端建立空库,得到git 库 urlgitremoteaddorigin<远程giturl># 此时,就可以用Sourcetree进行远程提交了。更新本地已经迁出的git库
# 测试 22 端口(SSH)telnet github.com22如果是用ssh-url克隆的远端库 e.g.gitclone --recurse-submodules git@github.com:openpnp/openpnp.git 就要配置本地的ssh-key对,在远端自己的git账号中添加ssh-key(认证)# 测试 22 端口(SSH)telnet github.com22如果正常,可以看到 SSH-2.0-xxxxxx 如果不正常,在远端账户重新添加SSH认证keygitfetch origin# 获取远程更新# 切到指定的分支,合并远程修改到指定的分支gitcheckout main# 切换到主分支gitmerge origin/main# 合并远程主分支统计工程总提交次数
$gitlog--all--oneline|wc-l74将linux路径显示为windows路径
在msys2-mingw64和sourcetree命令行中,都有将linux路径显示为windows路径的需求。
用pwd和cygpath可以进行路径转换,这2个程序都是git自带的。
chenx@ls3561 MINGW64 /d/3rd/openpnp_prj/openpnp-official/openpnp(my2d0_test1)$ wherepwdC:\Program Files\Git\usr\bin\pwd.exe chenx@ls3561 MINGW64 /d/3rd/openpnp_prj/openpnp-official/openpnp(my2d0_test1)$ where cygpath C:\Program Files\Git\usr\bin\cygpath.exe用法
chenx@ls3561 MINGW64 /d/3rd/openpnp_prj/openpnp-official/openpnp(my2d0_test1)$pwd/d/3rd/openpnp_prj/openpnp-official/openpnp chenx@ls3561 MINGW64 /d/3rd/openpnp_prj/openpnp-official/openpnp(my2d0_test1)$pwd-WD:/3rd/openpnp_prj/openpnp-official/openpnp chenx@ls3561 MINGW64 /d/3rd/openpnp_prj/openpnp-official/openpnp(my2d0_test1)$ cygpath-w/d/3rd/openpnp_prj/openpnp-official/openpnp D:\3rd\openpnp_prj\openpnp-official\openpnp chenx@ls3561 MINGW64 /d/3rd/openpnp_prj/openpnp-official/openpnp(my2d0_test1)$echo$(pwd)/d/3rd/openpnp_prj/openpnp-official/openpnp chenx@ls3561 MINGW64 /d/3rd/openpnp_prj/openpnp-official/openpnp(my2d0_test1)$ cygpath-w$(pwd)D:\3rd\openpnp_prj\openpnp-official\openpnp查看git库的建立时间
chenx@ls3561 MINGW64 /d/3rd/FreeCAD(main)$gitlog--reverse--pretty=format:"%ai"|head-12011-10-1013:44:52 +0000 chenx@ls3561 MINGW64 /d/3rd/FreeCAD(main)$gitlog--reverse--pretty=format:"%ai"--all|head-12011-10-1013:44:52 +0000 chenx@ls3561 MINGW64 /d/3rd/FreeCAD(main)$gitrev-list --max-parents=0--all|xargs-I{}gitlog-1--pretty=format:"%ai"{}|sort|head-12011-10-1013:44:52 +0000