git-bash
-
Windows下,git提供了一个Linux风格的命令行,叫git-bash
-
用例:解决乱码问题,Windows路径无效问题,并修改字体大小
-
乱码问题
-
解决方法:在git-bash右键->Options->Text,修改Local为zh_CN,Character set为UTF-8,还可以Select,修改字体大小
-
Windows路径无效问题
-
解决方法:给路径加上一对单引号
config
- 用例:对git最先要做的一个操作就是配置用户名和邮箱,否则无法commit
- 查看所有可以config的条目,非常之多
$ git config --list core.symlinks=false core.autocrlf=true core.fscache=true color.interactive=true color.ui=auto help.format=html diff.astextplain.textconv=astextplain rebase.autosquash=true filter.lfs.clean=git-lfs clean -- %f filter.lfs.smudge=git-lfs smudge -- %f filter.lfs.process=git-lfs filter-process filter.lfs.required=true credential.helper=!"D:/Software/PortableGit/mingw64/libexec/git-core/git-credential-store.exe" user.email=[email protected] user.name=DEDSEC_Roger credential.helperselector.selected=store core.repositoryformatversion=0 core.filemode=false core.bare=false core.logallrefupdates=true core.symlinks=false core.ignorecase=true remote.origin.url=https://<token>@github.com/DEDSEC-Roger/Speaker_Recognition.git remote.origin.fetch=+refs/heads/*:refs/remotes/origin/* branch.main.remote=origin branch.main.merge=refs/heads/main
- 但我们需要配置的并不多,只需要配置user.email和user.name即可,配置完后可以查看一下
$ git config --global user.name DEDSEC_Roger $ git config --global user.email [email protected] $ git config --global --list user.email=[email protected] user.name=DEDSEC_Roger # credential.helperselector是我之前设置的 credential.helperselector.selected=store
- git的默认编辑器是vim,可能对新手不太友好,可以改为nano
git config --global core.editor "nano"
- 如果系统重装了,或者项目的owner改变了,git需要重新连接git项目。只需要进入要管理的目录,然后
git config --global --add safe.directory <your_project_directory>
- 但是这不是一劳永逸的办法,因为每次重新连接git项目,都需要设置一下,因此最好是把文件owner改成之前的
# -R表示递归所有子文件夹,-v表示显示修改的过程 sudo chown <username> -Rv <directory>
clone
-
用例:从GitHub,clone某个仓库的某个分支(branch)到当前文件夹
-
找到main分支,复制HTTPS的网址
-
在本地新建一个文件夹,然后运行
$ git clone https://github.com/DEDSEC-Roger/Speaker_Recognition.git Cloning into 'Speaker_Recognition'... remote: Enumerating objects: 271, done. remote: Counting objects: 100% (11/11), done. remote: Compressing objects: 100% (10/10), done. remote: Total 271 (delta 5), reused 3 (delta 1), pack-reused 260 Receiving objects: 100% (271/271), 32.10 MiB | 1.09 MiB/s, done. Resolving deltas: 100% (50/50), done.
-
成功下载该仓库该分支的代码到本地了,是放在一个文件夹里面的,这个文件夹里除了.git文件夹,其他都称为工作区(working directory)
-
注意:clone包含.git文件夹,如果我们已经做了很多修改,那么.git文件夹会非常大,因为保存了以前的commit,可以采用–depth=1来限制只提取最近一次commit,并采用–branch来指定分支
$ git clone --depth=1 --branch=main https://github.com/DEDSEC-Roger/Speaker_Recognition.git 正克隆到 'Speaker_Recognition'... remote: Enumerating objects: 77, done. remote: Counting objects: 100% (77/77), done. remote: Compressing objects: 100% (75/75), done. remote: Total 77 (delta 0), reused 65 (delta 0), pack-reused 0 展开对象中: 100% (77/77), 完成.
status
- 用例:监控本地分支(Your branch)、缓存区(暂存区)(stage、index)和工作区有无发生修改
- 本地分支和缓存区都是隐藏的,在.git文件夹里,不影响工作区
- 修改文件夹里的Test.py,然后运行
$ git status On branch main Your branch is up to date with 'origin/main'. Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory) modified: Test.py no changes added to commit (use "git add" and/or "git commit -a")
- 会告诉你哪些文件被修改了,哪些修改还没有被添加到缓存区
add
- 用例:将工作区(下文省略)修改的文件,添加到缓存区,添加的是完整路径,因此添加单个文件会创建该文件的整个目录,因此add文件即可,不用担心目录不完整
- add只会添加工作区发生修改的文件,未修改的文件,即使add,也不会被放到缓存区
- add添加的语法有很多,如下
# 当前目录下所有文件 git add . # 当前目录下单个文件 git add filename # 当前目录下多个文件 git add filename1 filename2 filename3 # 当前目录下所有.py文件 # 一个*表示匹配任意数量字符 # 一个?表示匹配任一(包括无)字符 # .符号也会被匹配 git add *.py # 当前目录下所有.pyc, .pyo, .pyd文件 # 一个[]表示匹配括号内的任一字符,也可以在括号内加连接符,如[0-9]匹配0至9的数 git add *.py[cod] # 当前目录下除.py文件外的所有文件 # 一个!在前表示反转规则 git add !*.py # 整个文件夹,必须是非空文件夹 git add folder # folder文件夹下,以及子文件夹下的所有文件 git add folder/* # folder文件夹下,以及子文件夹下的所有.py文件 # 两个*表示匹配任意子文件夹 git add folder/**/*.py
- 比如说,在Profile文件夹下,粘贴了一个以Delete结尾的文件夹,这个文件夹里有.txt文件,现在回到Speaker_Recognition文件夹,要把.txt文件,添加到缓存区
$ git add Profile/*Delete/*.txt $ git status On branch main Your branch is up to date with 'origin/main'. Changes to be committed: (use "git restore --staged <file>..." to unstage) new file: Profile/ECAPA_TDNN_GLOB_c512-ASTP-emb192-ArcMargin-LM_Delete/dummy.txt Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory) modified: Test.py
commit
- 用例:把缓存区的文件都添加到本地分支
- commit必须用-m写信息,否则无法commit,如果不写信息就按了回车,会进入vim强行让你写,可以按下esc,然后输入:q,最后按下回车退出
- commit后status查看状态,会提示说本地分支多了一个commit
$ git commit -m "add files" [main 487222b] add files 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 Profile/ECAPA_TDNN_GLOB_c512-ASTP-emb192-ArcMargin-LM_Delete/dummy.txt $ git status On branch main Your branch is ahead of 'origin/main' by 1 commit. (use "git push" to publish your local commits) Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory) modified: Test.py no changes added to commit (use "git add" and/or "git commit -a")
restore
- 用例:进行工作区和缓存区的恢复操作
- 将工作区已修改的文件恢复到修改之前
$ git status On branch main Your branch is up to date with 'origin/main'. Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory) modified: Test.py no changes added to commit (use "git add" and/or "git commit -a") $ git restore .\Test.py $ git status On branch main Your branch is up to date with 'origin/main'. nothing to commit, working tree clean
- 将缓存区的文件恢复到工作区,工作区文件不变,相当于撤销add操作
$ git add .\Test.py $ git status On branch main Your branch is up to date with 'origin/main'. Changes to be committed: (use "git restore --staged <file>..." to unstage) modified: Test.py $ git restore --staged .\Test.py $ git status On branch main Your branch is up to date with 'origin/main'. Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory) modified: Test.py no changes added to commit (use "git add" and/or "git commit -a")
rm
- 用例:可用于撤销add,本质上是将指定的文件变成Untracked状态,所谓Untracked状态的文件,就是在clone到本地时,分支中没有的文件。建议用git restore --staged filename代替
- 操作后会显示delete了该文件,然后我们再把该文件改好,再次add该文件,就能把正确的更新放到缓存区
git add .\Test.py $ git status On branch main Your branch is up to date with 'origin/main'. Changes to be committed: (use "git restore --staged <file>..." to unstage) modified: Test.py $ git rm --cached .\Test.py rm 'Test.py' $ git status On branch main Your branch is up to date with 'origin/main'. Changes to be committed: (use "git restore --staged <file>..." to unstage) deleted: Test.py Untracked files: (use "git add <file>..." to include in what will be committed) Test.py $ git add .\Test.py $ git status On branch main Your branch is up to date with 'origin/main'. Changes to be committed: (use "git restore --staged <file>..." to unstage) modified: Test.py
reset
- 用例:如果后续又commit了一些文件,但是感觉commit错了,可以用reset,撤销commit操作
- 注意:reset会丢弃commit,当reset到某个commit后,该commit后面的commit会被全部丢弃
- 只对本地分支reset,不要对已经push到远程分支的commit,使用reset
# --soft表示退回本地分支的commit到缓存区 # HEAD后面跟几个~就是最近的几次commit # HEAD后面也可直接跟~数字,比如HEAD~~等价于HEAD~2 $ git reset --soft HEAD~ # --mixed表示退回本地分支的commit到缓存区,再把缓存区的添加全部去除 $ git reset --mixed HEAD~ # 慎用!--hard表示退回本地分支的commit到缓存区,再把缓存区的添加去掉 # 再把工作区的修改也恢复,工作区的恢复是全部恢复 $ git reset --hard HEAD~
- 由于
--hard
能够恢复本地工作区,所以reset可以用来从commit恢复文件# 首先,获取需要恢复的commit的id $ git log commit 4468947dc8de8bc88480a21c1572576b26c87e59 (HEAD -> master, origin/master, origin/HEAD) Author: DEDSEC_Roger <[email protected]> Date: Tue Feb 28 16:46:42 2023 +0800 scores/*, config.yaml, train.log commit 6587f7c2f72c64096b93f3b8928a71f384afeef1 Author: DEDSEC_Roger <[email protected]> Date: Tue Feb 28 16:41:51 2023 +0800 ecapa_tdnn, ecapa_tdnn_lm commit 8eff57d84861daf8bafe84212664dddaa2e600fe Author: DEDSEC_Roger <[email protected]> Date: Tue Feb 28 16:39:22 2023 +0800 extract_vox, prepare_data, score, score_norm # 根据commit的comment来确定需要恢复的commit # 比如第二个commit的id为6587f7c2f72c64096b93f3b8928a71f384afeef1 # 然后恢复 $ git reset --hard 6587f7c2f72c64096b93f3b8928a71f384afeef1
- 如果你没有commit任何东西,不要使用reset,因为这样会回退本地分支,这会导致本地分支与远程分支发生差异
Your branch and 'origin/main' have diverged, and have 1 and 2 different commits each, respectively. (use "git pull" to merge the remote branch into yours)
- 发生差异后,会导致无法push本地分支到远程分支,需要先pull远程分支
revert
- 用例:撤销commit,但不恢复文件,不丢弃commit,是较安全的撤销commit的方法
```bash
$ git log
commit b05c085c53f7f5e3beaa1054445c809ffedaaed0 (HEAD -> master)
Author: DEDSEC_Roger <[email protected]>
Date: Tue Feb 28 19:28:47 2023 +0800
modified test.txt
commit 5e440cbe2aed805fc19b0e995bc4c5f2622163ad
Author: DEDSEC_Roger <[email protected]>
Date: Tue Feb 28 19:07:11 2023 +0800
create test.txt
$ git revert 5e440cbe2aed805fc19b0e995bc4c5f2622163ad
CONFLICT (modify/delete): test.txt deleted in parent of 5e440cb...
create test.txt and modified in HEAD. Version HEAD of test.txt left in tree.
error: could not revert 5e440cb... create test.txt
hint: after resolving the conflicts, mark the corrected paths
hint: with 'git add <paths>' or 'git rm <paths>'
hint: and commit the result with 'git commit'
# commit还在
$ git log
commit b05c085c53f7f5e3beaa1054445c809ffedaaed0 (HEAD -> master)
Author: DEDSEC_Roger <[email protected]>
Date: Tue Feb 28 19:28:47 2023 +0800
modified test.txt
commit 5e440cbe2aed805fc19b0e995bc4c5f2622163ad
Author: DEDSEC_Roger <[email protected]>
Date: Tue Feb 28 19:07:11 2023 +0800
create test.txt
# 文件未被修改
$ git status
On branch master
Your branch is ahead of 'origin/master' by 2 commits.
(use "git push" to publish your local commits)
You are currently reverting commit 5e440cb.
(fix conflicts and run "git revert --continue")
(use "git revert --skip" to skip this patch)
(use "git revert --abort" to cancel the revert operation)
Unmerged paths:
(use "git restore --staged <file>..." to unstage)
(use "git add/rm <file>..." as appropriate to mark resolution)
deleted by them: test.txt
# 修改好文件后,再次add并commit
$ git add .
$ git commit -m "finish revert"
$ git log
commit 817c9918ca5272b31cf5caa95d7de4eeefbf779d (HEAD -> master)
Author: DEDSEC_Roger <[email protected]>
Date: Tue Feb 28 19:45:29 2023 +0800
finish revert
commit b05c085c53f7f5e3beaa1054445c809ffedaaed0
Author: DEDSEC_Roger <[email protected]>
Date: Tue Feb 28 19:28:47 2023 +0800
modified test.txt
commit 5e440cbe2aed805fc19b0e995bc4c5f2622163ad
Author: DEDSEC_Roger <[email protected]>
Date: Tue Feb 28 19:07:11 2023 +0800
create test.txt
```
checkout
- 用例:修改错了文件,从之前的commit恢复文件,不删除commit
# 修改错了test1.txt,提交了commit $ git log commit 27012e98329790632fdaa40a277347caa7099cda (HEAD -> master) Author: DEDSEC_Roger <[email protected]> Date: Tue Feb 28 19:56:16 2023 +0800 modify test1 commit 817c9918ca5272b31cf5caa95d7de4eeefbf779d Author: DEDSEC_Roger <[email protected]> Date: Tue Feb 28 19:45:29 2023 +0800 finish revert # 从“finish revert”恢复,但又不删除“modify test1” $ git checkout 817c9918ca5272b31cf5caa95d7de4eeefbf779d -- test1.txt # test1.txt已恢复,“modify test1”这个commit还在 $ git log commit 27012e98329790632fdaa40a277347caa7099cda (HEAD -> master) Author: DEDSEC_Roger <[email protected]> Date: Tue Feb 28 19:56:16 2023 +0800 modify test1 commit 817c9918ca5272b31cf5caa95d7de4eeefbf779d Author: DEDSEC_Roger <[email protected]> Date: Tue Feb 28 19:45:29 2023 +0800 finish revert
remote
- 用例:查看进行pull和push操作的远程分支的信息,由于GitHub要求token才能push分支,所以还需要进行仓库的地址设定
- 如果用了tizi,但是命令行里还是显示连接不上,需要设置tizi自启动,然后重启电脑
# 指定仓库名origin,查看该仓库的信息 # 直接git remote,查看连接了哪些仓库 $ git remote show origin * remote origin Fetch URL: https://github.com/DEDSEC-Roger/Speaker_Recognition.git Push URL: https://github.com/DEDSEC-Roger/Speaker_Recognition.git HEAD branch: main Remote branch: main tracked Local branch configured for 'git pull': main merges with remote main Local ref configured for 'git push': main pushes to main (local out of date)
- 先去GitHub申请token,官方教程在此,拿到token后,一定要复制保存到本地
- 然后设置远程仓库的地址,必须先设置这个带有token的地址,才能在GitHub顺利地push
$ git remote set-url origin https://<token>@github.com/DEDSEC-Roger/Speaker_Recognition.git $ git remote show origin * remote origin Fetch URL: https://<token>@github.com/DEDSEC-Roger/Speaker_Recognition.git Push URL: https://<token>@github.com/DEDSEC-Roger/Speaker_Recognition.git HEAD branch: main Remote branch: main tracked Local branch configured for 'git pull': main merges with remote main Local ref configured for 'git push': main pushes to main (local out of date)
pull
- 用例:拉取远程分支的更新,使本地分支与远程分支同步
up to date
# pull的对象是某个仓库的某个分支,加上仓库名origin和分支名main更严谨一些 $ git pull origin main remote: Enumerating objects: 7, done. remote: Counting objects: 100% (7/7), done. remote: Compressing objects: 100% (4/4), done. remote: Total 5 (delta 2), reused 0 (delta 0), pack-reused 0 Unpacking objects: 100% (5/5), 1.27 KiB | 81.00 KiB/s, done. From https://github.com/DEDSEC-Roger/Speaker_Recognition b41da3b..3149ba8 main -> origin/main Updating b41da3b..3149ba8 Fast-forward ...CAPA_TDNN_GLOB_c512-ASTP-emb192-ArcMargin-LM.onnx | Bin 24861931 -> 0 bytes Resource/origin.jpg | Bin 1852464 -> 0 bytes 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 Model/ECAPA_TDNN_GLOB_c512-ASTP-emb192-ArcMargin-LM.onnx delete mode 100644 Resource/origin.jpg # 此时再查看状态,本地分支的修改还在,而且新增的文件处于Untracked状态 $ git status On branch main Your branch is up to date with 'origin/main'. Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory) modified: Test.py Untracked files: (use "git add <file>..." to include in what will be committed) Profile/ECAPA_TDNN_GLOB_c512-ASTP-emb192-ArcMargin-LM_Delete/ no changes added to commit (use "git add" and/or "git commit -a")
push
- 用例:将本地分支push到远程分支,更新本地分支的修改到远程分支
- 要push前,可以git remote show对应仓库,如果仓库连不上,git remote show会失败,等成功了,再push,防止中途出问题
$ git remote show origin * remote origin Fetch URL: https://<token>@github.com/DEDSEC-Roger/Speaker_Recognition.git Push URL: https://<token>@github.com/DEDSEC-Roger/Speaker_Recognition.git HEAD branch: main Remote branch: main tracked Local branch configured for 'git pull': main merges with remote main Local ref configured for 'git push': main pushes to main (fast-forwardable) # push的对象是某个仓库的某个分支,加上仓库名origin和分支名main更严谨一些 $ git push origin main Enumerating objects: 7, done. Counting objects: 100% (7/7), done. Delta compression using up to 8 threads Compressing objects: 100% (4/4), done. Writing objects: 100% (4/4), 380 bytes | 380.00 KiB/s, done. Total 4 (delta 3), reused 0 (delta 0), pack-reused 0 remote: Resolving deltas: 100% (3/3), completed with 3 local objects. To https://github.com/DEDSEC-Roger/Speaker_Recognition.git af33ce1..251eb2b main -> main
.gitignore
- 用例:指定哪些文件被忽略,只对Untracked状态的文件有用
- .gitignore不是指令,而是一个文件,在创建GitHub仓库之初,就可以勾选创建.gitignore文件。之后再创建也是可以的,但是创建.gitignore文件前就存在的文件,都处于Tracked状态
- 不论是在本地分支还是远程分支,不论.gitignore有无指定忽略,Tracked状态的文件发生修改后,都会被git检索出来,参与同步
- .gitignore文件的语法,和add类似,不再赘述,给出一个小例子
# Customization Audio/**/*.wav Model/**/*.onnx Profile/**/*.npy # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] *$py.class # C extensions *.so
rm另一用法
使用前请备份要被删除的文件
- 用例:将全部文件都变成Untracked状态(.gitignore文件创建前的文件也变成Untracked状态了),然后将全部文件add回去,再commit、push,这样能将.gitignore指定忽略的文件从远程分支全部删除,不被忽略的文件保留
- 这样做就像是在创建GitHub仓库之初,就创建了.gitignore文件,git clone也不会下载Untracked状态的文件
$ git rm -r --cached . rm '.gitignore' rm '.vscode/launch.json' rm 'Audio.py' rm 'Audio/hzf_certain.wav' rm 'Audio/hzf_certain_2.wav' ... $ git status On branch main Your branch is up to date with 'origin/main'. Changes to be committed: (use "git restore --staged <file>..." to unstage) deleted: .gitignore deleted: .vscode/launch.json deleted: Audio.py deleted: Audio/hzf_certain.wav deleted: Audio/hzf_certain_2.wav ... $ git add . $ git status On branch main Your branch is up to date with 'origin/main'. Changes to be committed: (use "git restore --staged <file>..." to unstage) modified: Audio.py deleted: Audio/hzf_certain.wav deleted: Audio/hzf_certain_2.wav deleted: Audio/hzf_certain_3.wav deleted: Audio/hzf_certain_4.wav deleted: Audio/hzf_certain_5.wav ... $ git commit -m "completely update .gitignore" [main fa38978] completely update .gitignore 62 files changed, 1673 insertions(+), 1673 deletions(-) delete mode 100644 Audio/hzf_certain.wav delete mode 100644 Audio/hzf_certain_2.wav delete mode 100644 Audio/hzf_certain_3.wav delete mode 100644 Audio/hzf_certain_4.wav delete mode 100644 Audio/hzf_certain_5.wav ... $ git push origin main
branch
- 用例:重命名本地分支和远程分支
- 未关联远程仓库,重命名本地分支后,上传分支
# 正处于要进行重命名的本地分支master下 $ git branch -m main # 不处于要进行重命名的本地分支master下 $ git branch -m master main # 重命名后,关联远程仓库 $ git remote set-url origin https://<token>@github.com/DEDSEC-Roger/WeSpeaker.git # 上传分支,此时在远程,存在名为master的分支 $ git push origin main # 上传后,会存在master和main两个分支
- 已关联远程仓库,重命名本地分支后,再重命名远程分支
# 正处于要进行重命名的本地分支main下 $ git branch -m master # 不处于要进行重命名的本地分支master下 $ git branch -m main master # 重命名后,删除远程分支 $ git push origin --delete main # 删除远程分支后,最好再关联远程仓库一次 $ git remote set-url origin https://<token>@github.com/DEDSEC-Roger/WeSpeaker.git # 上传分支 $ git push origin master # 上传后,会存在master分支,关联远程分支 $ git branch --set-upstream-to=origin/master