Git

Git是现在非常流行的版本控制软件,同类软件的有svn。Github是流程的git仓库host网站,国内也有很多git host网站,例如git@OSC。这里有一份很好的教程

1. 安装使用

Windows下安装git

Windows下推荐使用github做的git for windows,最新的版本是2.51.1(2020/02/29),下载之后直接安装,安装选项(没有涉及到的选项按默认的来)(如果需要更改安装配置选项,只需要重新运行安装程序后重现选择即可):

  • Select components默认选择即可,可以勾上Use a Turetype font in all console windows,其它默认;一般我还会去掉Git GUI Here的勾选
  • Configuring the line ending conversions选择Checkout as-is, commit as-is,不改变git检出和提交的数据。
  • Configuring the terminal emulator to use with Git Bash,选择Use Windows default console window,这样cmd命令、telnet nodejs等程序可以正常运行。推荐使用Windows 10。(终端配置见最后一节)
  • Configuring extra options勾选上Enable symbolic links

Linux下安装git

对于CentOS 7,执行yum install git安装git。最好推荐升级到最新版本:

yum install http://opensource.wandisco.com/centos/7/git/x86_64/wandisco-git-release-7-2.noarch.rpm
# yum install http://opensource.wandisco.com/centos/6/git/x86_64/wandisco-git-release-6-1.noarch.rpm # for CentOS6
yum install git

生成ssh公钥并添加到github

进入Git Bash,执行ssh-keygen,一路回车完成。然后将C:\Users\用户名\.ssh\id_rsa.pub(windows)或~/.ssh/id_rsa.pub(linux)里面的内容贴到github的ssh keys配置中。

设置为保持密码

git config --global credential.helper store

2. 常用命令

配置自己的用户名和邮箱,每个git都推荐单独制定:

git config user.name pugwoo # 加上--global则是全局指定
git config user.email pugwoo@gmail.com

对于国外的github或bitbucket,如果比较慢,可以设置代理,支持http或socks5:

git config --global http.proxy http://proxyuser:proxypwd@proxy.server.com:8080

取消设置代理:

git config --global --unset http.proxy

检出代码,推荐使用ssh公钥的方式拉代码:

git clone git@github.com:pugwoo/j2se.git #如果提示输入yes/no,输入yes

添加文件到版本控制范围:

git add 文件名
git add -A # 添加所有文件
git add . # 添加当前文件夹所有文件,常用

删除文件(文件夹):

git rm 文件名 # 多个文件名用空格隔开
git rm -r 文件夹名
# 如果不想git把本地的文件删除掉,则加上--cached 选项

查看当前本地被修改但还没有提交的文件,包括新增、修改、删除的文件和文件夹:

git status # 如果没有修改会提示没有修改

查看本地未提交的文件的修改

git diff HEAD

提交修改到本地repo:

git commit -m "说明"
git commit -a -m "说明" # 使用-a选项将本地的修改文件直接提交,不用先执行git add了

查看本地git日志:

git log

从远程拉代码并合并到本地:

git pull

将“本地代码提交”提交到远程repo,执行之前记得git status看下修改的文件并git add .添加到commit范围再git commmit -m "msg"

git push

显示本地设置的远程remote repo:

git remote -v

关于清除本地修改的命令

还原本地修改:

git checkout .

删除本地生成的,没有纳入git索引范围的文件:

git clean -f # 可以指定特定文件,没有指定则是全部untracked文件
git clean -f -d # 可以指定文件夹,没有指定则是全部untracked文件

3. 分支相关命令

branches模型

显示分支:

git branch # 查看本地分支(带星号的是当前分支)
git branch -a # 查看本地和远程所有分支

创建一个新分支,基于当前的分支:

git branch 新分支名称

切换分支:

git checkout 分支名称

假设你现在基于远程分支”origin”,创建一个叫”mywork”的分支:

git checkout -b mywork origin

从当前分支检出一个新分支并切换到该新分支:

git checkout -b 新分支名称

注:git创建的分支和svn创建的分支一个不同点:git的分支会把原分支的所有log加在当前分支上,看起来当前分支就好像从第一次提交到现在一样;而svn则看不到原分支过去的log记录,所以svn每次合并要看同一个文件的修改记录就很麻烦。

删除分支:

git branch -d 分支名称
git branch -D 分支名称  #(这个是无论分支是否合并到主干都删除)
git push origin :Branch1   #在github远程端删除一个分支,(分支名前的冒号代表删除)

将b分支合并到当前分支:

git merge b

将本地分支推送到远程(本地和远程的分支是对等的,名称相同,不能由本地的A分支提交到远程B分支。):

git push -u origin feature_branch_name
git push --set-upstream origin feature_branch_name # 加上--set-upstream后就不用每次都打git push origin Branch1,而是直接git push即可
git push --all -u  # 将所有分支都push到远程

关于rebase和merge的区别: git pull默认是merge的方式,merge会将两条分支合并并新建一个新节点,看起来就是两条分支合并成一条。rebase则将另一条分支的修改点整入到当前分支,看起来就像一条分支,没有合并。

参考这篇博客,如果你想让”mywork”分支历史看起来像没有经过任何合并一样,你也许可以用:

git rebase:
git checkout mywork
git rebase origin

更多的文档参考:Git分支的创建与合并

关于TAG分支

git tag # 列出所有的tag
git tag -l 1.* # 搜索tag
git tag v1.0 # 添加tag
git tag -a v1.0 -m "日志" # 添加tag
git tag -a v1.1 8a5cbc2 # 为之前的commit添加tag,commit的标志是log commit的前缀
git tag -d v1.0 # 删除tag
git push origin --tags # 将本地的tag上传到远程

4. github创建项目

创建github项目时,推荐选择Initialize this repository with a README并选择好编程语言设置好.ignore,就可以git clone出项目。

如果想自己初始化项目,则不选择初始化,然后提交到远程:

mkdir tmp
cd tmp
echo # justtest >> README.md # 新建一个文件
git init # 初始化git
git add README.md # 将文件加入到git仓库
git commit -m "first commit" # 提交到本地仓库
git remote add origin https://github.com/pugwoo/justtest.git # 添加远程仓库 
git push -u origin master # 将本地仓库推送到远程,下次就只用git push

对于github而言,它是一个版本控制的文件系统,并不关心里面的内容是项目还是文本。所以一个github repo下,是只有一个项目,还是每个目录一个项目,还是更深的结构关系,对于github来说都是不关心的。

5. git ignore文件

该文件可以指定哪些文件git可以忽略掉不纳入版本控制,常用的ignore文件内容:

忽略点号.开头的文件

.*
!/.gitignore

6. 创建git服务器

实际上,服务器端并没有执行git的任何服务器程序,git客户端只需要.git即可。

无论是新的git还是gitclone出来的已有git,假设当前目录A下有.git目录,那么在目录A的父目录执行:

git clone --bare A A.git

就可以创建出一个A.git的文件夹,这个文件夹即服务端数据。

或者是直接创建一个服务端.git文件夹:

mkdir a.git
cd a.git
git init --bare

对于客户端,相当于登录上服务器使用数据文件,执行:

git clone 用户名@服务器:/path/to/A.git

真实项目中,我们会使用gitea或gitlab等工具来搭建git服务器。

7. 常用操作和常见问题

全量迁移仓库

git clone --mirror <URL to my OLD repo location>
cd <New directory where your OLD repo was cloned>
git remote set-url origin <URL to my NEW repo location>
git push -f origin

持续同步一个git仓库到另外一个git仓库

git clone --mirror GIT_URL # clone一个git出来先
cd GIT_DIR # 进入git目录
git remote add --mirror=fetch secondary GIT_URL2 # 把要被同步的git加入进来

git fetch origin # 拉
git push secondary --all # 推,上面这两个命令可以持续执行以保持同步

第一次提交git push时,出现No refs in common and none specified; doing nothing.

解决:执行git push origin master

github上和fork的源仓库保持同步

进入自己的仓库,点击Compare按钮,选择左侧为自己的仓库,右侧为fork的源仓库,然后create pull request,再自己合并自己的pull request即可。

让git记住https拉取方式的密码

git config --global credential.helper store

这个配置会将密码保存在~/.git-credentials文件下,请小心保密。

重置更多参考

999.git bash 终端配置

终端类型

安装选项 Configuring the terminal emulator to use with Git Bash,可以重新运行安装程序进行更改配置。

  • Use MinTTY (the default terminal of MSYS2)
    Git Bash will use MinTTY as terminal emulator,which sports a resizable window,non-rectangular selections and a Unicode font. Windows console programs (such as interactive Python) must be launched via ‘winpty’ to work in MinTTY.
    Git Bash将使用MinTTY作为终端模拟器,该模拟器具有可调整大小的窗口,非矩形选区和Unicode字体。 Windows控制台程序(如交互式Python)必须通过’winpty’启动才能在MinTTY中运行。
  • Use Windows’ default console window
    Git will use the default console window of Windows (“cmd.exe”),which works well with Win32 console programs such as interactive Python or node.js , but has a very limited default scroll-back,needs to be configured to use aUnicode font in order to display non-ASCII characters correctly,and prior to Windows 10 its windows was not freely resizable and it only allowed rectangular text selections.
    Git将使用Windows的默认控制台窗口(“cmd.exe”),该窗口可以与Win32控制台程序(如交互式Python或node.js)一起使用,但默认的回滚非常有限,需要配置为使用unicode 字体以正确显示非ASCII字符,并且在Windows 10之前,其窗口不能自由调整大小,并且只允许矩形文本选择。

这两种配置无法共存,mintty可能会带来更好的体验,比如说选中即复制功能,字体的支持也更好。

在mintty/windowsCmd两种选项中分别运行tree.com指令,会发现mintty出现乱码,此时可以通过winpty tree.com解决。

mintty下nodejs编译时的兼容性问题待验证,按照网上的说法,使用winpty nodejs 可以解决。

终端配置

  • 终端窗口右键Options可以设置语言/字体/使用习惯等,在体验上比windows好
  • ./.bash_profile
alias ll='ls -lh'
alias tree='winpty tree.com'
alias node='winpty node'

export PS1='\[\033]0;$TITLEPREFIX:$PWD\007\][\[\033[1;32m\]\W\[\033[36m\]`__git_ps1`\[\033[0m\]]# '
  • 关于PS1
默认PS1值:
'\[\033]0;$TITLEPREFIX:$PWD\007\]\n\[\033[32m\]\u@\h \[\033[35m\]$MSYSTEM \[\033[33m\]\w\[\033[36m\]`__git_ps1`\[\033[0m\]\n$'

命令行样式:(窗口标题为当前完整路径)
sapluk@sapluk-k550d MINGW64 /d/programs/Git/bin
$ ll
total 132K
-rwxr-xr-x 1 sapluk 197121 43K  1月 13 20:31 bash.exe*
-rwxr-xr-x 1 sapluk 197121 43K  1月 13 20:31 git.exe*
-rwxr-xr-x 1 sapluk 197121 43K  1月 13 20:31 sh.exe*

修改后的PS1值:
'\[\033]0;$TITLEPREFIX:$PWD\007\][\[\033[1;32m\]\W\[\033[36m\]`__git_ps1`\[\033[0m\]]# '

命令行样式:(窗口标题为当前完整路径)
[~]# cd /d/programs/Git/bin/
[bin]# ll
total 132K
-rwxr-xr-x 1 sapluk 197121 43K  1月 13 20:31 bash.exe*
-rwxr-xr-x 1 sapluk 197121 43K  1月 13 20:31 git.exe*
-rwxr-xr-x 1 sapluk 197121 43K  1月 13 20:31 sh.exe*
文档更新时间: 2020-05-04 10:57   作者:nick