0%

git 日常使用技巧

Git这个工具也使用了很长一段时间了。对于一些简单的使用也有了一些了解,之前都是记在OneNote上面的,往博客搬,顺便整理一下。


.gitignore和.gitattributes用法

可以直接看官方说明

  • The Ignoring Files chapter of the Pro Git book.
  • gitattributes Template

    .gitignore

    .gitigonre用来标志你想要忽略的文件或者目录
  • /mtk/ 过滤整个文件夹(注意最后面的’/‘表示文件夹)
  • *.zip 过滤所有.zip文件
  • /mtk/do.c 过滤某个具体文件
  • **/1.txt 过滤所有子目录下的 1.txt 文件

模拟一个场景,假如我们只需要管理/mtk/目录中的one.txt文件,这个目录中的其他文件都不需要管理,那么我们就需要使用:

1
2
/mtk/*
!/mtk/one.txt

注:在测试的时候写成/mtk/的话并不会把/mtk/one.txt加入到版本管理中

示例说明如下:

1
2
3
4
5
6
7
8
9
10
a)规则:fd1/*
说明:忽略目录 fd1 下的全部内容;注意,不管是根目录下的 /fd1/ 目录,还是某个子目录 /child/fd1/ 目录,都会被忽略;
b)规则:/fd1/*
说明:忽略根目录下的 /fd1/ 目录的全部内容;
c)规则:
/*
!.gitignore
!/fw/bin/
!/fw/sf/
说明:忽略全部内容,但是不忽略 .gitignore 文件、根目录下的 /fw/bin/ 和 /fw/sf/ 目录.

如何你想找一个好用的.gitignore文件可以看下这个https://github.com/github/gitignore

.gitattributes

.gitattributes则是GitHub会在你的项目上传后自动分析它是由何种语言编写,然后给出一个统计结果,如 C 40%, Java 55%, XML 5%.有时候我们希望进行干预,创建 .gitattributes 文件,加入

1
*.c linguist-language=C++

这样所有 .c 文件都会被识别为 C++。此外,还可以用 Git 属性让其知道哪些是二进制文件(以防 Git 没有识别出来),以及指示怎样处理这些文件。
还有其他的用法这里暂不说明了。(其实我也不会了hh)

重建.gitignore的方法

有时候需要重建.gitignore,可以使用如下的方法

1
2
3
4
git rm -r --cached .  #清除缓存  
git add . #重新trace file
git commit -m "update .gitignore" #提交和注释
git push origin master #可选,如果需要同步到remote上的话

在一般情况只需要修改,然后使用git status就可以看到变化了


常用指令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
~ 初始化创建仓库
$ git init

~ 查看历史版本
$ git log
//带参数的这个可以只看版本号和提交的版本信息
$ git log --pretty=oneline

~ 查看当前缓存区状态
$ git status

~ 将所有修改添加到缓存区
$ git add -A

~ 提交版本
$ git commit -m "This is a version!"
~ 抓取github的最新提交
$ git pull
//从远程develop分支抓到当前分支
$ git pull origin develop

~ 将本地的分支推送到远程github仓库
$ git push -u origin master //-u换成-f则是强制推送
//由于远程库是空的,我们第一次推送master分支时,加上了-u参数,Git不但会把本地的master分支内容推送的远程新的master分支,还会把本地的master分支和远程的master分支关联起来,在以后的推送或者拉取时就可以简化命令。

~ 合并分支
//将develop分支更新的内容合并到当前分支
$ git merge origin develop

~ 比较修改操作
$ git diff HEAD -- readme.txt //注意--和readme.txt之间的空格
这个是比较工作区和版本库里面最新版本的区别
$ git version1 version2 src //版本号一般前6位即可
比较两个版本之间src文件夹之间的区别,--后加文件名

~ 版本回退
$ git reset --hard HEAD^ //一个^就是回退一个版本
如果需要回退多个版本则使用多个^或者写成HEAD~5,数字决定退回次数使用$ git reflog记录了你的每一次命令,如果版本回退后悔了可以使用指令前进
$ git reset --hard commit_id

~ 撤销git add的操作
$ git rm --cached <file>
~ 合并多个commit (~2表示合并最近的两次commit)
$ git rebase -i HEAD~2
然后修改pick成s,只留下需要的一个pick
保存修改显示的commit注释保存即可

有关 rebase 的用法可以看【Git】rebase 用法小结


git tag

  • 命令 git tag 可以显示所有的标签
  • 命令 git tag <tagname> 用于新建一个标签,默认为 HEAD,也可以指定一个 commit id
  • 命令 git tag -a <tagname> -m "message" 可以指定标签信息
  • 命令 git push origin <tagname> 可以推送一个本地标签
  • 命令 git push origin --tags 可以推送全部未推送过的本地标签
  • 命令 git tag -d <tagname> 可以删除一个本地标签
  • 命令 git push origin :refs/tags/<tagname> 可以删除一个远程标签
  • 命令 git checkout <tagname> 可以切换到对应标签的提交点,需要注意的是,在 checkout 切换到标签位置 之后进行的提交不属于任何分支,因为此时已经分离了 head 指针,一般的做法是 创建一个新的分支,然后再 commit 进行后续的操作

git warning:LF will be replaced by CRLF解决方法

对于当前项目中的config进行修改,直接在项目目录执行即可
$ git config core.autocrlf false
也可以加上--global参数在全局中修改
git config --global core.autocrlf false
其实上是修改的.gitconfig文件,对项目的修改是project/.git/config,全局则是修改~/.gitconfig
修改之后的情况如下,这里以我的~/.gitconfig文件为例

1
2
3
4
5
6
7
8
9
# This is Git's per-user configuration file.
[user]
name = xuan
email = cugxuan@qq.com
# Please adapt and uncomment the following lines:
# name = xuan
# email = xuan@xuandeMacBook-Pro.local
[core]
autocrlf = false

最好的习惯是所有的文本文件都是用LF(ASCII码中的’\n’)结尾
不要是用Windows自带的记事本进行打开,浏览时换行不会正常(因为Windows识别CRLF为换行)

如果需要查看已经配置过的设置,可以使用git config --list查看

Git 文件名大小写无法修改的问题

在本地修改了文件名或者目录的大小写,但是每次 push 发现在 GitHub 上面都没有上传成功,并未完成修改,解决方法如下:

  1. 使用 git 执行命令,将该项目下的 git 识别大小写关闭
    1
    2
    3
    4
    5
    $ git config core.ignorecase false
    各个选项和意思如下
    false -- do not use workarounds for non-case-sensitive filesystems (current) (default)
    off no -- do not use workarounds for non-case-sensitive filesystems
    true yes on -- use workarounds for non-case-sensitive filesystems
  2. 在设置了忽略大小写之后,使用 $ git status 就可以看到大小写有关文件的修改
    这时候需要删除远程仓库中不需要的文件夹和文件
    1
    2
    3
    4
    5
    6
    # 删除 Test 文件夹中的记录
    $ git rm --cached Test -r
    # 然后推送到远端
    $ git add -A
    $ git commit -m "rm files"
    $ git push origin master

    举个例子,你仓库中有文件夹 test
    .
    └── test
    └── 1
    上传一次 commit
    然后 $ mv test Test
    .
    └── Test
    └── 1
    $ git status
    On branch master
    Your branch is up to date with ‘origin/master’.
    显示并没有改动,原因是没有区分大小写
    $ git config core.ignorecase false
    $ git status
    Untracked files:
    (use “git add …” to include in what will be committed)
    Test/
    然后 commit,会发现 GitHub 上有 testTest 两个文件夹,本地只有 Test
    于是删除 test 的缓存,推送到远端
    $ git rm –cached test -r
    $ git add -A
    $ git commit -m “rm files”
    $git push origin master


修改git remote url

重新修改git的remote url
法一
$ git remote set-url origin git@github.com:test/thinkphp.git
法二
$ git config -e
直接编辑其中origin的url就行了,退出时记得保存

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[core]  
repositoryformatversion = 0
filemode = false
bare = false
logallrefupdates = true
symlinks = false
ignorecase = true
hideDotFiles = dotGitOnly
[remote "origin"]
fetch = +refs/heads/*:refs/remotes/origin/*
url = https://github.com/x/thinkphp.git
[branch "master"]
remote = origin
merge = refs/heads/master

修改commit版本中的注释

修改已经commit版本里面的注释

1
2
3
4
5
6
7
8
9
# 如果你的注释写错了
$ git commit --amend
//如果需要修改当前版本的倒数第二次状态
$ git rebase -i HEAD~2
//会出现pick:***的几行,将你要改的那行的pick改成edit然后退出
//这时使用$ git log你会发现最上面的版本已经变成了你想改的那个
$ git commit --amend
//修改版本提交注释之后执行下面的就成功了
$ git rebase --continue

删除本地和远程的分支

1
2
3
4
# 删除远程的分支
$ git push origin --delete branch_name
# 删除本地的分支
$ git branch -d branch_name

开发测试环境

在实际写代码的过程中一般至少有两个环境,测试和线上环境,如何来使用git维护我们的开发进程,并且在测试develop环境和线上online环境中都可以比较好的进行管理,这里使用分支的合并。
首先创建好的工程然后初始化git,在这个分支上进行代码的编写,然后提交一个版本

1
2
3
4
5
6
7
8
# 创建仓库,并且修改内容
$ git init
$ echo 124>>1.txt
# 提交版本
$ git add -A
$ git commit -m "init"
# 推到远程
$ git push -u origin master

然后开始创建develop分支和online分支

1
2
3
4
5
6
7
8
# 创建develop分支并且切换过去
$ git checkout -b develop
# 推送到远端,现在处于develop分支
$ git push -u origin develop
# 创建online分支切换过去
$ git checkout -b online
# 推送到远端,现在处于online分支
$ git push -u origin online

然后在online分支中修改自己的配置文件(连接线上的数据库)
保持测试数据库和线上的数据结构的一致性,在develop分支进行开发

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 在online分支上修改配置文件并且commit
$ echo 11>>1.txt
$ git add 1.txt
$ git commit -m "修改online内容"
# 切换到develop分支进行开发
$ git checkout develop
# 开发了一个版本之后进行提交
$ git add -A
$ git commit -m "a version"
$ git push origin develop
# 然后切换到online分支,将新开发的功能合并进去
$ git checkout online
$ git merge origin develop
$ git push origin online
# 推送到远端之后就可以再次切换回到develop分支进行开发了
$ git checkout develop

这样就完成了远程的online分支的更新,然后在服务器上部署online分支的代码
在远端仓库更新了之后进行git pull更新即可。(当然也可以使用web hook进行自动的部署更新)


配置文件在项目中显示了账户密码

把自己的项目扔到了github上面,但是在配置文件中有账号密码等信息,这样不就暴露了吗。
解决方法:在第一次的时候将空的配置文件上传,然后在.gitignore文件中添加对应的文件进行忽略。
比如在WordPress中,下载下来的代码里面根目录下是wp-config-sample.php文件,需要手动复制重命名为wp-config.php,做法也是在.gitignore中忽略该文件,给一个sample文件来避免私密信息的泄露。


如何使用 HTTP 代理

在进行 clone 的时候经常会遇到速度特别慢的情况,一般比较好的方法是用梯子进行代理
有两种使用代理的方法,使用 git 的代理设置使用系统的代理设置,这里假设代理使用 1080 端口进行 HTTP 代理,使用 1087 端口进行 socks5 代理,那么设置方法如下:

使用 git 的代理设置,在设置了代理之后可以在 ~/.gitconfig 文件中看到对应的设置

1
2
3
4
5
6
7
8
9
http代理:
$ git config --global https.proxy http://127.0.0.1:1087
$ git config --global https.proxy https://127.0.0.1:1087
socks5代理:
$ git config --global http.proxy socks5://127.0.0.1:1080
$ git config --global https.proxy socks5://127.0.0.1:1080
取消代理
$ git config --global --unset http.proxy
$ git config --global --unset https.proxy

使用系统的代理设置,如果不写到 ~/.bashrc 或者 ~/.zshrc 之类的配置文件不能永久生效,但是这样用起来也挺方便的,oh-my-zsh 可以很方便找历史

1
2
3
4
5
6
http代理
$ export http_proxy=http://127.0.0.1:1087;export https_proxy=http://127.0.0.1:1087;
$ git clone xxx
socks5代理
$ export http_proxy=socks5://127.0.0.1:1080;export https_proxy=socks5://127.0.0.1:1080;
$ git clone xxx

参考资料

听说好看的人都关注了我的公众号《泫言》