基本概念:

workispace(工作区): 本地电脑中clone 的文件夹下,就是工作区;

Repository(版本库): 工作区中的.git 隐藏文件就是git 的版本库; 这里存了很多东西,其中有stage(index) 暂存区,还有自动创建的第一个分支master, 以及指向master 的一个指针 HEAD;

remote(远程仓库): server 端保存的版本库信息,一般来讲这里包含了所有推送的结果;

 

对于这三者之间的一些操作关系如下:

 

本地工作区中文件含义:

1. .git/refs/ : heads/      #本地branch 相关信息
                remotes/ #remote 端的相关信息

配置设定: 

SSH key生成与配置, 实现local  与 remote 之间传输;

ssh-keygen -t rsa -C "youremail@example.com" #这里选择自己的mail
cat ~/.ssh/id_rsa.pub # 然后将这个文件中的信息复制到github SSH keys 中
ssh -T git@github.com   #配置完成以后,可以确认下配置成功

#可以使用下面的命令配置一些个人信息, 把下面“” 中内容换成个人信息
git config --global user.name "xxx"
git config --global user.email "xxx@github.com"

 

 

.gitignore  #忽略指定的文件

在使用过程中,对于一些特定的文件,只想留在本地自己用,如果每次都要手动选择,很麻烦,所以可以当前工作区建立.gitignore 文件,来忽略一些指定的文件(正则规则), 也可以将该文件上传; 如果只是自己用, 那么可以把.gitignore 也加入其中, 只是每次都clone 到本地都要新建这个文件;

git l-files --others #列出哪些文件没有被git 管控

.ignore 中由对应不同的编程语言的一些已经配置好的信息:github/gitignore

 

alias  #快捷键设定,这里注意配置时候作用范围;

在下面的操作中,有可能会有下面的类型的命令,就是对于一些命令缩写的绑定;可以使用下面git cmd 来实现这个快捷键使用;

git config --global(local) --list #列出当前git的全局(当前仓库)配置信息,包含快捷键
git config --local/global/system alias.st status #快捷键设定,这里local用来选择配置信息的范围

 

作用范围,类似linux 系统;

  a. 针对当前repo 的配置信息存储在 /.git/config , 可以在配置过程中传递 --local 来读写该文件;

  b. 针对当前账户下的配置信息,linux 系统中就是在当前用户目录下: ~/.gitconfig , windows 系统是在C:\USERS\用户名\.gitconfig 文件中;可以通过git config --global 选项读写此文件,这会对当前账户下所有仓库生效;

  c. 针对系统级配置文件: /etc/gitconfig (没试过), 可以传递 --system 方式读写该文件,注意权限问题;

 1 amend = commit --amend
 2 amendf = commit --amend --no-edit
 3 br = branch
 4 ct = commit
 5 co = checkout
 6 cp = cherry-pick
 7 df = diff
 8 ds = diff --staged
 9 l = log
10 lg = log --graph --all --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(bold white)— %an%C(reset)%C(bold yellow)%d%C(reset)' --abbrev-commit --date=relative
11 sa = stash apply
12 sh = show
13 ss = stash save
14 st = status
15 lp = log --pretty=oneline --abbrev-commit --graph
下面使用alias

  

常见操作:

1. 建立本地的库 与 远程库之间关联(该操作其实一般很少用,不过简单列下);

  在github 建立remote 以后,我们就可以将本地库链接到这个repo 下面;github 下面也有一些基本操作教程如下:

mkdir GitLearn 
cd GitLearn
git init 
git remote add LEARN git@github.com:guigym/GitLearn.git   #这里将本地名字为LEARN,常见为origin, 这里设定了特殊的值;
echo 'add the 1st file for new repo;' > readme_file
git add --all  
git commit -m 'add the 1st file for new repo;'
git push --set-upstream LEARN master   #将LEARN 与 remote master 链接在一起,下面操作都会用到LEARN

 

git remote add <name> <url> #上面使用这个命令增加了remote url 到本地;
git remote remove <name>  #删除上面add 的name(还有rename 进行重命名)
git remote -v # 此时也可以通过这个命令显示远程url 链接到本地的信息

 

git clone git@github.com:guigym/GitLearn.git #如果只是下载已有的repo,可以直接用repo 命令。

 

 2. 常用的增查改删操作:

#查
git status : 查看当前branch 下的状态;

# 增、改
git add : 是把当前改动添加到暂存区,

#删
git rm <filename> 可以将文件在工作区 与 暂存区删除;
rm <filename> 也可以将文件直接删除,  

    

  

  你在后期工作中,修改了一些文件,然后要查看文件改动哪里?

#查 details
git diff : 比较工作区 与 暂存区 区别, 也可以指定文件查看不同;
git diff --cached : 比较暂存区 与 仓库的差别
git diff HEAD  : 比较工作区 与 仓库的差别,这里HEAD 可以为指定的commit ID

git difftool commitID1 commitID2 #查看两次commit的差异;

  如果有文件改错了,怎么恢复;(这里对于改动文件在不同地方(工作区、暂存区,库), 有不同操作):

git reset filename/ git restore --staged filename : 取消暂存区的改动 到 工作区;
git checkout HEAD filename : 暂存区 改动变为 远程库原始状态;其中HEAD 可以为之前的commit ID, delete 的文件也可以这样恢复
git reset --hard HEAD^ : 将工作区 与 暂存区 改动都丢弃,恢复至当前HEAD前一个commit 状态,(HEAD^^:前两个,HEAD~3: 前3(n)个
git restore filename / git checkout filename(早期在filename 之前加--, 以区别branch 建立/切换;)#工作区改动恢复;
git reset --soft HEAD^ #对于已经commit,但是还没有push 的文件,将改动从 repo 恢复到 暂存区;
git clean -fd #删除一些新增的文件;

其中 git reset 还有很多其他选项 --hard(暂存区、工作区改动都丢弃)/mixed(缓存区改动都丢弃)...
git reset --help 查看帮助文件,其中有下面的这个table 展示不同option 对应的结果;

 

  对于修改远程库内容,一般不推荐,如果只是回退某个提交,可以使用下面命令;

  如果要回滚,有其他方式,一般不推荐回滚。

git revert <commit ID> #回退某个提交

  

  工作做完了,要提交到远程时操作:

#推送remote
git commit -m #标注当前推送的改动描述,方便以后查阅
#如果commit 信息错误,那么要更改commit message;
git commit --ammend -m 'new message;' #更改最近一次commit message, 结果如下图所示
git push #推送到remote

#查看当前branch 下过往的提交信息

git log (file) #查看过往提交信息,这里也有很多选项,下面列了一些个人常用的,可以指定文件查看该文件的修改历史
git log -p # 查看每次commit 的具体修改部分,add 的信息不会显示
git lot --stat #快速查看各个commit 的修改文件简略信息
git log --pretty=oneline --abbrev-commit # 简略显示各个修改信息,想看整体树状图,可以 --graph 选项

 

关于分支:

 git 中主分支为 master 分支, HEAD 指向master,master 再指向最新提交;新建branch,就相当于新建一个类似master 的指针;

  每次切换分支,就是将HEAD不断移动到不同的指针位置;而在合并分支过程中,最简单,直接的方式,就是将master 指向 branch 当前的提交,就可以实现合并(merge);之后删除branch ,也就相当于把当前的branch 指针删除了

  在实际工作流程中,一般大家不会直接在master  中工作;下面时一个个人觉得比较适合团队合作时规范。

  michael/bob:是个人完整自己工作中具体case;

  dev:是个人将完成的某个case 合并的信息;

  master 是某个正式release的版本的;也是比较适合对外展示项目进度的部分;

   

在实际工作中,常见的branch 相关的操作:

  建立新的branch 

 

git checkout -b new_branch ##建立一个新的branch,并跳转进这个branch
git checkout master/ git switch master #切换到不同的branch (git 2.23 版本中引入git switch 来代替 git checkout 作为切换branch 的命令;)
git branch -d new_branch  ##删除本地new_branch, -D 相当于强制删除(等价-d -f)
git push <remote> -d(--delete) branch_name #删除远端branch,remote是远端名字(这里是LEARN)
git branch --all(-av, -rv) ##显示remote/local 所有的branch
git branch new_branch commitID #基于commitID 建立new_branch, 等价(git checkout -b new_branch commitID);
#完成工作,推送到remote 

git checkout -b 2nd_branch  
git status  
echo 'init the new file for 2nd_branch;' > 2nd_branch
git status  
git add --all  
git commit -m 'add the init file for 2nd_branch;'
git push --set-upstream LEARN 2nd_branch   #remote 存在该branch 时候,可以直接push; 另外注意这里使用LEARN(不是origin),是因为前面在建repo 时候我们命名为LEARN;

  

纯粹的推送一个新的branch,没有文件变更;

  

工作结束,review完成后,我们就可以将当前branch merge 到dev;

git checkout dev #切换到最终被merge 的branch
git merge 2nd_branch #将2nd_branch merge 到当前的branch; 这里使用fast-foward 默认方式;

从下图中,可以看出默认的merge 方式使用fast-forwad 选项,如果没有其他的改动,相当于直接把dev 转移到当前branch, 然后HEAD也还是指向dev; 这里保存了2nd_branch 中各个提交的信息;

  如果不使用ff 方式merge,那么这部分作为一个branch 修改,然后再合并到dev 中, 这个过程会保留下来;

git merge --no-ff 3rd_branch #不适用fast-forward 方式;

 

  还有中--squash 方式merge,这是相当于把某个branch 所有改动作为一个改动,然后在dev上面提交一个commit merge 到 dev 中;

  这也会丢失原来branch commit 信息(原来branch 被删除后)

  

  删除4th_branch 以后,原来branch 上面信息都会丢失;

  

 在合并过程中,常见的conflict 处理

  一般在merge 之前最好先git pull/fetch, 这两者有所差别,注意区分使用;

git fetch LEARN #取回远程remote 所有改动到本地的repo
git fetch LEARN dev #取回remote LEARN dev 中的改动到本地,但是不会改变工作区;

git pull #取回remote LEARN dev 中的改动到本地,同时merge工作区内容,并把head 至于最新commit

 使用fetch后的结果: 

  

  使用pull 的结果:

  

   处理conflict, 然后用--no-ff merge ,注意观察其中brach tree 的变化过程;

  

   其他一些命令:

git branch -v #展示local 存在的branch 相关信息;
git branch --merged master #展示被merged 到master上面的branch name;

 

关于tag(标签)

  在实际工作中,即使使用规范管理git 流程,但是每个commit ID 是随机hash 值,commit message 又不一定能完全体现变动;

  所以我们一般都是用特定版本号,rev1..., 这个信息可以通过tag 与某个commit ID 绑定;

  新建/删除 tag

git tag tagname (commit ID)   ##新建tag,(没有commit ID, 默认当前commit);
git push origin tagname  ##推送当前tag 到server
git push origin --tags       ##推送所有tag 到server


git tag -d tagname     ##删除tag    
git push origin :refs/tags/tagname  ##推送删除操作到server

 

其他使用技巧:

1. git 的帮助信息查找

git --help #显示git 基本帮助信息
git help -a #显示所有的subcommand
git help -g #显示git 一些定义配置相关帮助信息

git help <subcommand> #显示当前subcommand/概念相关的帮助信息

2. 查看git 历史命令对应的commit ID; 

git reflog # 查看命令历史中对应的各个commit ID, 方便hard reset 以后要head 转移到新的部分;

 

3. git stash;

使用场景:假如突然要求fix bug,需要先切换到 其他分支,但当前分支的代码没有提交,直接切换分支,会将当前分支的新增的代码也会增加到 master 分支,而代码此时又不能commit ,这时候可以使用 git stash ;

git stash(等价git stash save) # 保存当前状态,只会保存被trach 的文件;
git stash save --all "message"    # 可以保存track/untrack 的文件, message 里面可以记录一些信息
git stash list #返回缓存的列表, 显示所有的保存的stash;
git stash show stash@{x} #显示stash x(默认为0) 改动的文件, 选项 --all(显示改动的内容);
git stash apply stash@{x} #将 stash x 中的改动,加入当前branch中改动的, 但是不会删除该stash;适合多分支应用该缓存;
git stash pop stash@{x} # 与apply 差别在于,这个会将堆栈中该stash删除;
git stash drop stash@{x} #将stash x 从堆栈中中删除;
git stash clear #清空当前堆栈

 在某些场景下,会发生恢复失败,可以考虑使用下面的命令试试

git stash show -p | git apply -3  #相当于将stash 中存储的所有改动都apply
git show stash@{0}:changedFile  #显示当前stash{0}中修改的changedFile 改动状态,注意该文件如果有更新;

git stash 与其他一些命令的结合

$ git diff stash@{0}^1 stash@{0} -- <filename>  #显示stash 存储的第一个父级 与 stash 中内容的差别,

$ git checkout stash@{0} -- <filename> (git show stash@{0}:<filename> > <new filename> #输出重定向) 从stash 中检查单个文件;

  

4. 其他常用命令:

git cherry-pick :可以将一个commit id 中的改动,复制到其他branch; 不过二者改动一摸一样,但是commit id 是不一样;
git blame <file>: 查看file文件的每行改动的commit相关信息;

  

5. git cheet sheet(from Liao's blog)

 

6. 一个帮助学习git 的游戏网站: https://learngitbranching.js.org/

 

APPENDIX:

上面所使用的remote git repo link

posted on 2022-07-21 20:34  学海一扁舟  阅读(220)  评论(0编辑  收藏  举报