GIT使用总结

说明

  1. 本文为工作中git使用总结
  2. 本文没有商业目的

gerrit

merge the Gerrit branch to another Gerrit branch

stackoverflow

To the best of my knowledge, you have 2 options currently

  • Force push to refs/heads. It is just a fast-forward, so in theory everything has already been reviewed and verified. There is no point in doing so again, so just skip that process and push to refs/heads rather than refs/for.

  • Go ahead and create a merge commit. Use git merge --no-ff - this will create a merge commit even though it isn’t necessary in your fast-forward situation. Then the merge commit can be uploaded, reviewed, verified, and merged like normal.

git add

git add -h
git add -u # -u, --update update tracked files

git am

git am (--continue | --skip | --abort) PATCH_NAME  //打补丁
git apply --reject  PATCH_NAME  //强制应用补丁
git add FILE_NAME //添加到缓冲区

git cat-file

git cat-file: show info and contents of objects file.

  • blob 对应仓库里的普通文件,当将一份文件 add 到仓库里时,git 将会产生一个 blob 对象存于 objects 目录下。

  • tree 对应仓库里的一个目录,当做一次 commit 时,git 将会为新增的目录产生 tree 对象存于 objects 目录下。

  • commit 大致可以视为工作目录的快照。commit 时创建工作目录的快照 git 做了三件事:

    1. commit 对象的哈希
    2. 如果这个文件没有改变,git 仅仅只把压缩文件的名字哈希值放入工作目录快照。如果文件发生了变化,git 会压缩它,然后把压缩后的文件存入 object 目录,再把压缩文件的名字哈希值放入工作目录快照。
    3. 工作目录快照的哈希

注意:如果文件的哈希值是“89faaee…”,git 会把这个文件存在 object 目录的 “89” 目录下,然后命名这个文件为 “faaee…”。

git checkout-index

Will copy all files listed from the index to the working directory (not overwriting existing files).

--prefix=<string>
When creating files, prepend <string> (usually a directory including a trailing /)

Export tree of tag v1.6.0 to specific directory

git read-tree v1.6.0 | git checkout-index -a --prefix=/home/nocent/work/git/tf1.6.0/

git config

$ git config --global user.name "YOUR NAME" 
$ git config --global user.email "YOUR EMAIL ADDRESS"

git diff

$ git diff HEAD

这条命令显示的内容会在执行“git commit -a”命令是被提交,这里-a参数 自动将所有修改或删除的文件添加到index区,但对那些没有添加到git库的新创建的文件没有影响,也就是显示不出区别。

$ git diff --cached

上面的命令会显示你当前的索引和上次提交间的差异;这些内容在不带"-a"参数运行 "git commit"命令时就会被提交。

$ git diff test

这会显示你当前工作目录与另外一个叫’test’分支的差别。你也可以加上路径限定符,来只 比较某一个文件或目录。

$ git diff HEAD -- ./lib

上面这条命令会显示你当前工作目录下的lib目录与上次提交之间的差别(或者更准确的 说是在当前分支)。

如果不是查看每个文件的详细差别,而是统计一下有哪些文件被改动,有多少行被改 动,就可以使用 --stat 参数。

$ git diff --stat

No newline at end of file

When doing a git diff it says No newline at end of file. What’s the significance of the message and what’s it trying to tell us?

It indicates that you do not have a newline (usually '\n', aka CR or CRLF) at the end of file.

That is, simply speaking, the last byte (or bytes if you’re on Windows) in the file is not a newline.

The message is displayed because otherwise there is no way to tell the difference between a file where there is a newline at the end and one where is not. Diff has to output a newline anyway, or the result would be harder to read or process automatically.

Note that it is a good style to always put the newline as a last character if it is allowed by the file format. Furthermore, for example, for C and C++ header files it is required by the language standard.

比较两次提交的同一个文件的差异

git diff commit-id-old commit-id-new -- filename

git format-patch

基于上几次内容打包

  • git format-patch HEAD^ 有几个^就会打几个patch,从最近一次打起
  • git format-patch HEAD^^ 最近的二个patch内容

以下代码作用同上

  • git format-patch -1
  • git format-patch -2
  • git format-patch -1 -4 //可以打包版本2,3的patch,但是发现有时候会把最近4个包都打包出来,具体原因未知

note

  • git format-patch的补丁,使用git am命令打patch

一般而言,为了保留git log的记录,我们在做patch的时候会使用git format patch的命令来生成一个patch,在应用patch的时候会选择git am来打上patch.一般的patch会包含N个文件的补丁,假设
有其中一个文件发生了conflict,那么am的过程就会停止,这时候需要我们手动去解决冲突,然后才能继续.

2.用到的命令
git format-patch -N //制作一个补丁,N表示生成几个patch,默认是一笔commit一个patch

git fetch and git pull

git中从远程的分支获取最新的版本到本地有这样2个命令

git fetch

相当于是从远程获取最新版本到本地,不会自动merge

git fetch <远程主机名> <远程分支名>:<local分支名>

  • 省略local 分支名 但不省略 远程分支名,则fetch到本地的 FETCH_HEAD 上
  • 省略local 分支名 并且省略 远程分支名,获取最新remote版本信息到本地,

获得代码

git checkout -b branch_name  FETCH_OUT

下面的命令含义:

git fetch origin master
git log -p master..origin/master
git merge origin/master
  1. 首先从远程的origin的master主分支下载最新的版本到origin/master分支上
  2. 然后比较本地的master分支和origin/master分支的差别
  3. 进行合并

上述过程其实可以用以下更清晰的方式来进行,但对origin/master有不同的影响:

git fetch origin master:tmp   没有更新origin/master
git diff tmp
git merge tmp

从远程获取最新的版本到本地的tmp分支上,之后再进行比较合并到本地 master分支上

git pull

git pull <远程主机名> <远程分支名>

  • 省略<远程分支名>,则 pull 到当前分支 remote-tracking 的那个 <远程分支名> 并合并到当前分支上
  • 不省略<远程分支名>,则 pull 到本地的 FETCH_HEAD 上,并合并到当前分支

git pull 命令执行两个操作:

  1. 从远程分支(remote branch)抓取修改的内容
  2. 把它合并进当前的分支

相当于是从远程获取最新版本并merge到本地当前分支

git pull origin master

Example:
Update the remote-tracking branches for the repository you cloned from, then merge one of them into your current branch:

$ git pull, git pull origin

Normally the branch merged in is the HEAD of the remote repository, but the choice is determined by the branch..remote and branch..merge options; see git-config(1) for details.

Merge into the current branch the remote branch next:

$ git pull origin next

This leaves a copy of next temporarily in FETCH_HEAD, but does not update any remote-tracking branches. Using remote-tracking branches, the same can be done by invoking fetch and merge:

$ git fetch origin
$ git merge origin/next

上述命令其实相当于git fetch 和 git merge在实际使用中,git fetch更安全一些,因为在merge前,可以查看更新情况,然后再决定是否合并结束。

git fetch:

Depending on the operation, git will use one of the following refspecs, if you don’t provide one on the command line. is the name of this file in $GIT_DIR/branches and defaults to master.

git fetch uses:

refs/heads/<head>:refs/heads/<branch>

git push uses:

HEAD:refs/heads/<head>

EXAMPLES
Update the remote-tracking branches:

$ git fetch origin

The above command copies all branches from the remote refs/heads/ namespace and stores them to the local refs/remotes/origin/ namespace, unless the branch..fetch option is used to specify a non-default refspec.

Using refspecs explicitly:

$ git fetch origin +pu:pu maint:tmp

This updates (or creates, as necessary) branches pu and tmp in the local repository by fetching from the branches (respectively) pu and maint from the remote repository.

git log

–summary
Output a condensed summary of extended header information such as creations, renames and mode changes.

git push

git push命令用于将本地分支的更新,推送到远程主机。它的格式与git pull命令相仿。

$ git push <远程主机名> <本地分支名>:<远程分支名>

注意,分支git push推送顺序的写法是 <来源地>:<目的地>

  1. git push 如果省略远程分支名,则表示将本地分支推送与之存在”追踪关系”的远程分支(通常两者同名),如果该远程分支不存在,则会被新建。

     $ git push origin master
    

    上面命令表示,将本地的master分支推送到origin主机的master分支。如果后者不存在,则会被新建。

  2. 如果省略本地分支名,则表示删除指定的远程分支,因为这等同于推送一个空的本地分支到远程分支。

     $ git push origin :master
     # 等同于
     $ git push origin --delete master
    

上面命令表示删除origin主机的master分支。

  1. 将本地所有与远程分支之间存在追踪关系的分支推送到远程对应的分支,则本地分支和远程分支都可以省略。

     $ git push origin
    

    上面命令表示,本地所有与远程分支之间存在追踪关系的分支推送到origin主机的对应分支。

  2. 如果当前分支只有一个追踪分支,那么主机名都可以省略。

     $ git push
    
  3. 如果当前分支与多个主机存在追踪关系,则可以使用-u选项指定一个默认主机,这样后面就可以不加任何参数使用git push。

     $ git push -u origin master
    

    上面命令将本地的master分支推送到origin主机,同时指定origin为默认主机,后面就可以不加任何参数使用git push了。

for gerrit

$ git push remote_name HEAD:refs/for/branch_name
// example: git push origin HEAD:refs/for/master

git tag

  1. what is a tag in git

    A tag is used to label and mark a specific commit in the history.
    It is usually used to mark release points (eg. v1.0, etc.).

    Although a tag may appear similar to branch, a tag, however, does not change.
    It points directly to a specific commit in the history.

    You will not be able to checkout the tags if it’s not locally in your repository so first, make sure that the tag exists locally by doing:

    # --all will fetch all the remotes.
    # --tags will fetch all tags as well
    git fetch --all --tags --prune
    

    Then check out the tag with the tags/ prefix by running:

    git checkout tags/<tag_name> -b <branch_name>
    

    In the follow sample you have 2 tags version 1.0 & version 1.1, you can checkout them out with any of the following:

    git checkout A  ...
    git checkout version 1.0  ...
    git checkout tags/version 1.0  ...
    

    All of the above will do the same since tag is only a pointer to a given commit.

  2. How to see the list of all tags

    # list all tags
    git tag
    
    # list all tags with given pattern ex: v-
    git tag --list 'v-*'
    
  3. How to create tags

    There are 2 ways to create a tag:

    # normal tag 
    git tag 
    
    # annotated tag
    git tag -a
    

    The difference between the 2 ways is that that the when creating an annotated tag you can add metadata like you have in a git commit: name, e-mail, date, comment & signature

  4. How to delete tags?

    Don’t forget to remove the deleted tag from the server with push tags

    # delete any given tag
    git tag -d <tag name>
    
  5. Sharing Tags

    By default, the git push command doesn’t transfer tags to remote servers. You will have to explicitly push tags to a shared server after you have created them. This process is just like sharing remote branches.

    git push origin <tagname>
    

git rebase

Assume the following history exists and the current branch is “topic”:

// branch:
      A---B---C topic
     /
D---E---F---G master

From this point, the result of either of the following commands:

git rebase master
git rebase master topic

would be:

// branch:
              A'--B'--C' topic
             /
D---E---F---G master

git rebase 的交互模式只需要传入一个参数 -i 即可,同时还需要指定对哪些提交进行处理,如:

git rebase -i HEAD~4

上述命令指定了对当前分支的最近四次提交进行操作。

多个commit合并

合并最新三个提交:

  1. 从HEAD版本开始往过去数3个版本

    git rebase -i HEAD~3
    
  2. 指名要合并的commit id 之前的那一个commit id

    git rebase -i da49f2b
    

    请注意da49f2b这个版本是不参与合并的。

    • pick 的意思是要会执行这个 commit;
    • squash 的意思是这个 commit 会被合并到前一个commit。

git read-tree

Reads the tree information given by into the index, but does not actually update any of the files it “caches”. (see: git-checkout-index(1)). Manual:

man git-read-tree

command:

# read tag v1.6.0 information to index
git read-tree v1.6.0 --index-output index_out

git remote

git remote set-url

usage: git remote [-v | --verbose]  
   or: git remote add [-t <branch>] [-m <master>] [-f] [--tags|--no-tags] [--mirror=<fetch|push>] <name> <url>  
   or: git remote rename <old> <new>  
   or: git remote remove <name>  
   or: git remote set-head <name> (-a | --auto | -d | --delete |<branch>)  
   or: git remote [-v | --verbose] show [-n] <name>
   or: git remote prune [-n | --dry-run] <name>  
   or: git remote [-v | --verbose] update [-p | --prune] [(<group> | <remote>)...]  
   or: git remote set-branches [--add] <name> <branch>...  
   or: git remote set-url [--push] <name> <newurl> [<oldurl>]  
   or: git remote set-url --add <name> <newurl>  
   or: git remote set-url --delete <name> <url>  
    -v, --verbose         be verbose; must be placed before a subcommand

git remote show origin

$ git remote show origin
* remote origin
  Fetch URL: ssh://xuxin-m@172.19.120.13:29418/ns/cv/ocr
  Push  URL: ssh://xuxin-m@172.19.120.13:29418/ns/cv/ocr
  HEAD branch: master
  Remote branch:
    master tracked
  Local branch configured for 'git pull':
    master merges with remote master
  Local ref configured for 'git push':
    master pushes to master (up to date)

git reset

--hard    Matches the working tree and index to that of the tree being
          switched  to. Any changes to tracked files in the working tree since
          <commit> are lost.

--merge
          Resets the index to match the tree recorded by the named commit, and
          updates the files that are different between the named commit and
          the current commit in the working tree.

The git reset --merge is meant to be a safer version of git reset --hard, when your changes and somebody else changes are mixed together, trying to carry our changes around.

git rev-parse

gitdir=$(git rev-parse --git-dir); scp -p -P 29418 xuxin-m@172.19.120.13:hooks/commit-msg ${gitdir}/hooks/

proxy

git config --global http.proxy http://username:password@proxy.server.com:port
git config --global https.proxy http://username:password@proxy.server.com:port

issues

How do I push amended commit to the remote Git repository?

answer

> git commit --amend

# Unfortunately the commit can't be pushed back to the repository. It is rejected like this:
> git push origin
To //my.remote.repo.com/stuff.git/
 ! [rejected]        master -> master (non-fast forward)
error: failed to push some refs to '//my.remote.repo.com/stuff.git/'

Here is a tip to recover from the situation after you have pushed out the amended commit with --force (or +master).

  1. Use git reflog to find the old commit that you amended (call it old_id), and we’ll call the new commit you created by amending new_id.
  2. Create a merge between old_id and new_id, recording the tree of new_id, like git checkout new_id && git merge -s ours old_id.
  3. Merge that to your master with git merge master.
  4. Update your master with the result with git push . HEAD:master.
  5. Push the result out with git push origin master.

Then people who were unfortunate enough to have based their work on the commit you obliterated by amending and forcing a push will see the resulting merge will see that you favor new over old. Their later merges will not see the conflicts between old and new that resulted from your amending, so they do not have to suffer.

减少.git的大小

下面是具体的操作方法:

  1. 运行 gc ,生成 pack 文件(后面的 --prune=now 表示对之前的所有提交做修剪,有的时候仅仅 gc 一下.git 文件就会小很多)

    $ git gc --prune=now
    
  2. 找出最大的三个文件

    $ git verify-pack -v .git/objects/pack/*.idx | sort -k 3 -n | tail -3
    1debc758cf31a649c2fc5b0c59ea1b7f01416636 blob   4925660 3655422 14351
    c43a8da9476f97e84b52e0b34034f8c2d93b4d90 blob   154188651 152549294 12546842
    2272096493d061489349e0a312df00dcd0ec19a2 blob   155414465 153754005 165096136
    
  3. 查看那些大文件究竟是谁(c43a8da 是上面大文件的hash码)

    $ git rev-list --objects --all | grep c43a8da
    c43a8da9476f97e84b52e0b34034f8c2d93b4d90 data/bigfile
    

4.移除对该文件的引用(也就是 data/bigfile)

```
$ git filter-branch --force --index-filter "git rm --cached --ignore-unmatch 'data/bigfile'"  --prune-empty --tag-name-filter cat -- --all
```

5.进行 repack

```
$ git for-each-ref --format='delete %(refname)' refs/original | git update-ref --stdin
$ git reflog expire --expire=now --all
$ git gc --prune=now
```

6.查看 pack 的空间使用情况

```
$ git count-objects -v
```
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值