Git命令

总结经常使用到的git命令。

init repository

在将写好的工程上传到远端git服务器时,需要以下几个步骤:

初始化本地repository。

1
git init

对本地repository进行git管理。

1
2
git add *
git commit -m "some info"

关联远端repository。

1
git remote add origin https://github.com/yourgithubID/gitRepo.git 

这个 https://github.com/yourgithubID/gitRepo.git 必须存在,需要提前到github上建好。当然这里不限于github,其他git服务器也可以。

将本地仓库push到远程仓库

1
git push -u origin master 

由于在建立github repository时,在master分支创建了README.md,在push时候出现错误。
可以通过如下命令进行代码合并【注:pull=fetch+merge]

1
git pull --rebase origin master

执行上面代码后可以看到本地代码库中多了 README.md 文件。 再执行语句 git push -u origin master 即可完成代码上传到github。

github新建本地仓库并将代码提交到远程仓库 如何解决failed to push some refs to git

clone

--depth <depth> 可以加速repository的下载速度,指定commit history中的depth条记录。

比如,下条只取最近一次commit的history。

1
git clone --depth 1 git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git

submodule

仓库使用了其他仓库,可将其他仓库当作子模块,通过submodule来管理,只需要在必要时更新子模块即可。 git将submodule有关的信息保存在两个地方:

  • .gitmodules: 有版本控制,修改后会同步到其他仓库,使用 submodule 相关命令时候会自动更新
  • .git/config: 需要手动更新,或者执行同步命令 submodule sync 将新的配置从 .gitsubmodule 拷贝至此。

clone 时候下载 submodule

1
git clone --recursive YOUR-GIT-REPO-URL

子模块代码更新:

1
2
git submodule sync
git submodule update --init --recursive

7.11 Git 工具 - 子模块

branch

  • list branches
1
git branch -a
  • checkout a specific branch
1
git checkout <branch_name>
  • Create the branch on your local machine and switch in this branch

    1
    git checkout -b [name_of_your_new_branch]

  • Push the branch on github

    1
    git push origin [name_of_your_new_branch]

或者首次使用 -u 选项,之后仅仅使用git push即可。

1
git push -u origin <branch>
+ How do I push a new local branch to a remote Git repository and track it too?

  • Delete a branch on your local filesystem

    1
    git branch -d [name_of_your_new_branch]

  • To force the deletion of local branch on your filesystem

    1
    git branch -D [name_of_your_new_branch]

  • Delete the branch on github

    1
    git push origin :[name_of_your_new_branch]

Create a new branch with git and manage branches

tag

git可以对某一时间点的版本打标签tag

  • 列出所有tag
1
2
3
git tag  
git tag -l
git tag -l 'v3.14.*'
  • checkout a specific tag
1
git checkout tags/<tag_name>

Download a specific tag with Git

  • add tag
1
2
git tag -a v2.1.0 -m "xyz feature is released in this tag."
git tag v2.0.0

push tag

just push particular tag

1
git push origin v1.0.3

push all tags:

1
git push --tags

Create a tag in a GitHub repository

  • delete tag
1
2
3
4
// delete a remote tag
git push --delete origin v1.0.0
// also delete the local tag
git tag --delete tagname

How to delete a remote tag?

diff/patch

生成patch

  • single file
    1
    git diff main.c > test.patch
  • all files
    1
    git diff > test.patch

应用patch

  • check patch file

    1
    git apply --stat test.patch
    or
    1
    git apply --check test.patch

  • apply patch

    1
    git apply test.patch

version management

git reset

版本回滚,向前回滚两个版本,可以用 HEAD~2,也可以使用7位commit id号。

1
2
git reset HEAD~2
git reset 1234567

末端的两个提交现在变成了悬挂提交。也就是说,下次 Git 执行垃圾回收的时候,这两个提交会被删除。
当需要跳转回时,查看消失的两个commit可以使用git reflog命令。

1
git reflog

Revert

顾名思义,版本还原,即撤销一个提交的同时会创建一个新的提交。
还原倒数第二个commit。

1
git revert HEAD~2

revertreset 区别是revert会改变提交历史,而reset不会。

undo all changes

  • unstage all files you might have staged with git add
1
git reset
  • revert uncommitted changes
1
2
3
git checkout .
# or
git reset --hard HEAD
  • remove all local untracked files

preview files to be deleted!

1
git clean -n

then remove all untracked files.

1
git clean -fdx

git undo all uncommitted or unsaved changes

ignoring changes to a single already versioned file

本次提交时忽略某一文件。

1
2
git add -u
git reset -- main/dontcheckmein.txt

Add all files to a commit except a single file

completely ignore a specific single file preventing it from being created at repository

完全忽略某一文件: 在仓库根目录创建 .gitignore 文件,并将要忽略的文件相对路径写入。

.gitkeep

git无法追踪一个空的文件夹,当用户需要追踪(track)一个空的文件夹的时候,按照惯例,大家会把一个称为.gitkeep的文件放在这些文件夹里。

主要用在:使git忽略一个文件夹下的所有文件,并保留该文件夹。

1
2
3
4
5
6
7
8
# .gitignore 

# ignore all files in lib/
lib/*
# except for .gitkeep
!.gitkeep
# ignore TODO file in root directory,not subdir/TODO
/TODO

当.gitignore采用上面的写法时,git会忽略lib文件夹下除了.gitkeep外的所有文件。

+.gitkeep说明

gitignore without binary files

1
find . -executable -type f >>.gitignore

gitignore does not work

.gitignore 忽略的是没有加入到仓库中的文件,如果已经添加到仓库,需要先删除。
这条命令会将文件从仓库中删除,但不会物理删除。然后提交更改即可。

1
git rm --cached files

或者简单粗暴全部删除再提交。

1
2
git rm -rf --cached .
git add .

git checkout error

git切换分支时出错:

error: The following untracked working tree files would be overwritten by checkout

这是由于一些untracked working tree files引起的问题。解决方法:

1
git clean -d -fx

git clean 参数:

  • -n 显示将要删除的文件和目录;
  • -x 删除忽略文件已经对git来说不识别的文件
  • -d 删除未被添加到git的路径中的文件
  • -f 强制运行

github

为了方便管理repository,免去每次push时候输入账户名和密码,接下来我们需要生成SSH公私钥对,并将公钥上传到 project->Settings->Deploy keys->Add deploy key。 SSH免密登录只针对以 git@github.com:torvalds/linux.git 形式的url访问的仓库,如果当前仓库以 HTTPS访问,需要先转换下。

1
git remote set-url origin <SSH url>
比如: git remote set-url origin git@github.com:torvalds/linux.git,查看 remote url 是否生效: git remote -v

首先检查是否已经存在 SSH key

1
ls -al ~/.ssh

出现类似

id_dsa.pub
id_ecdsa.pub
id_ed25519.pub
id_rsa.pub

如果想继续使用上述密钥,可直接将公钥拷贝出来;否则,要继续自行生成。

Generating a new SSH key and adding it to the ssh-agent

1
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"

如果想要保存不一样的位置或者名称,在下面的提示信息中输入即可。

Enter a file in which to save the key (/home/you/.ssh/id_rsa): [Press enter]

将 SSH key 添加到 ssh-agent 中。

1
2
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_rsa

执行ssh-add时出现 Could not open a connection to your authentication agent 。 可能当前SHELL不支持,退出当前SHELL即可。

1
ssh-agent bash
再次执行
1
2
ssh-add ~/.ssh/id_rsa
ssh-add -l

之后将 ~/.ssh/id_rsa.pub 内容拷贝到github的project->Settings->Deploy keys->Add deploy key。

这时执行 push 命令可能还会出现输入密码的问题,或者说没有权限。
查看 .git/config 文件查看传输协议, 如果是https模式改为ssh模式即可。

Github Deploy Key 操作如何避免输密码

github如何向开源项目提交pr

  1. fork 到自己的仓库
  2. git clone 到本地
  3. 上游建立连接
    git remote add upstream 开源项目地址
  4. 创建开发分支 (非必须)
    git checkout -b dev
  5. 修改提交代码
    1
    2
    3
    4
    git status 
    git add .
    git commit -m "message"
    git push origin branch
  6. 同步代码三部曲
    1
    2
    3
    git fetch upstream 
    git rebase upstream/master
    git push origin master
  7. 提交pr
    去自己github仓库对应fork的项目下new pull request

git fork后同步 upstream repository

分两个步骤, 1. 给fork配置远程仓库

查看远程仓库。

1
git remote -v

指定一个可以同步的远程upstream 仓库。

1
git remote add upstream https://github.com/ORIGINAL_OWNER/ORIGINAL_REPOSITORY.git

可以再次验证新的远程的upstream 仓库。

1
git remote -v

  1. 同步fork

从上游仓库 fetch 分支和提交点,所有上游分支并会被存储在本地分支,比如 master分支的提交会存储在 upstream/master。

1
git fetch upstream

切换到本地分支(比如master)

1
git checkout master

将 upstream/master分支的更新merge到本地master分支。

1
git merge upstream/master

提交更新

1
git push origin master

gitlab或github下fork后如何同步源的新更新内容?
Configuring a remote for a fork
Sync a fork of a repository to keep it up-to-date with the upstream repository.

fatal: remote error: Git repository not found

远程仓库存在但是在clone或者pull时候报错不存在,可以通过查看并清理认证缓存方式解决(Credential Issues)。

首先执行 git config -l | grep credential.helper 确认机器是否有系统缓存,当返回值不为空时说明机器有认证缓存。

credential.helper有多个模式,分别为 cachestoreosxkeychainmanager-core

  • cache 模式会将凭证存放在内存中一段时间。 密码永远不会被存储在磁盘中,并且在15分钟后从内存中清除。
  • store 模式会将凭证用明文的形式存放在磁盘中,并且永不过期。
    • 该模式为通用模式,所有操作系统均可能出现该模式缓存,清理手段如下: cat ~/.gitconfig ,在文件内找到 credential 对应的缓存文件路径,一般默认为~/.git-credentials,查询出缓存文件路径后,可直接删除掉该文件,也可通过编辑该文件来修改认证缓存信息,认证缓存格式为https://用户名:密码@github.com
  • osxkeychain 模式,该模式为Mac系统独有,它会将凭证缓存到你系统用户的钥匙串中。 这种方式将凭证存放在磁盘中,并且永不过期
    • 该模式清理手段如下:通过钥匙串,搜索git相关的凭证,点击进入后可以看到缓存的用户名称并清除。
  • manager-core 模式,该模式为windows系统独有,效果类似于“osxkeychain” 模式
    • 该清理手段如下:开始-->控制面板-->所有控制面板项-->凭据管理器-->清除和git相关记录的凭据

[Fix] ‘Fatal: Repository Not Found’ Error In Git