Git

Git 命令

Posted by nomadli on December 14, 2015

git官方中文教程

.git目录

  • COMMIT_EDITMSG git commit -m的最后一次信息,下次可直接使用
  • config git基础配置、远程地址、工作分支配置
  • description web说明文件
  • HEAD 当前活动工作分支
  • index 列出修改的文件名、文件内容并排序
  • pack
  • hooks 事件触发脚本目录
  • info/exclude 排除文件、目录
  • logs
    log信息:父commit-md5、当前commit-md5、提交者、-m信息
    refs/heads/master 每个分支当前的所有log信息
    HEAD 当前工作分支的所有log信息
    
  • objects
    git cat-file -t md5文件名
      blob 类型为 git add 后添出现的文件, git cat-file -p md5文件名 内容为修改的文件内容
      tree 类型为 git commit 后当前所有文件的当前md5
      commit 类型 git commit 时提交的tree的md5、提交者、修改者、commit -m信息
    
  • refs
    heads/master 各分支的当前commit-md5
    tags 各tags的当前commit-md5
    

svn 命令

  • svnadmin create name
  • svn co file:///path
  • svn add .
  • svn ci -m “ci is commit” . –no-unlock
  • svn lock -m “why need lock” –force .
  • svn unlock path
  • svn update/up -r version path -r还原
  • svn status/st -v path
  • svn log path
  • svn diff/di path
  • svn revert path
  • svn resolved path
  • svn rm -m “remove tree or file” http://*
  • svn import -m “add tree or file” fatherfload http://*
  • svn copy http://xx http://xx -m “crate tage”
  • svn info –username xxx –password xx –no-auth-cache svn://xxx 显示svn信息
  • svn log -l 10 /xx/xx 查看最后10个提交历史
  • svn mkdir –parents http:// http:// -m “创建多个目录包括父目录”
  • svn move http://SRC http://DST 等同于svn copy+svn delete

git svn 命令

  • git svn clone –stdlayout –authors-file=authors.txt http://sxx gxx
  • git svn clone –trunk=/trunk –branches=/branches –branches=/bugfixes –tags=/tags –authors-file=authors.txt http://sxx gxx
  • git svn clone -rxxx:HEAD –prefix=svn/ http://
  • git rebase 同步远程库
  • git svn dcommit 提交到svn
  • git svn reset -hash -p && git svn fetch 当本地有修改svn远程也修改,hash是开始修改的前一个提交
  • git rebase –onto remotes/git-svn trunk本地有修改,远程也有修改

修改svn服务器地址

  1. Edit the svn-remote url URL in .git/config to point to the new domain name
  2. Run git svn fetch – This needs to fetch at least one new revision from svn!
  3. Change svn-remote url back to the original url
  4. Run git svn rebase -l to do a local rebase (with the changes that came in with the last fetch operation)
  5. Change svn-remote url back to the new url
  6. Run git svn rebase should now work again!

git迁移到SVN

  1. 创建标准svn库 trunk branches tags
  2. git svn init -s –no-minimize-url svn-url -T trunk -b branches -t tags 添加标准svn
  3. git svn fetch 更新svn历史到git
  4. git show-ref trunk 显示svn分支当前最后提交
  5. git log –pretty=oneline master tail -n 1 显示git第一条commit
  6. echo “git 第一条md5 svn 最后一条md5” » .git/info/grafts 把git第一条提交及以后的提交放到svn最后一条后
  7. git svn dcommit

git分支提交到SVN

  1. 创建svn的branch
  2. git svn fetch 更新svn
  3. git checkout branch 切换到分支
  4. git checkout -b temp-branck 创建临时分支
  5. git rebase remotes/branch 把本地分支合并到远程分支
  6. git svn dcommit
  7. git branch -D temp-branck

从git分支更新svn分支

  1. 修改.git/config [svn-remote “branck”] url = svn/branches fetch = :refs/remotes/branch [branch “local-branch”] remote = . merge = refs/remotes/branch
  2. git svn dcommit

svn转git

  1. git svn clone svn://yip@112.74.112.220/ecs/branches/responsive/ios/XXX –no-metadata –trunk Trunk –branches Branches –tags Tags XXX
  2. 修复git命令 git filter-branch –tag-name-filter cat –msg-filter ‘sed -e “s/\\!/!/g”’ –env-filter ‘if [ “$GIT_AUTHOR_EMAIL” = “saurik@saurk.com” ]; then GIT_AUTHOR_EMAIL=”saurik@saurik.com”; fi; if [ “$GIT_COMMITTER_EMAIL” = “saurik@saurk.com” ]; then GIT_COMMITTER_EMAIL=”saurik@saurik.com”; fi’ – –all ```shell

    初始化本地仓库

    git svn init -T http://xx/svn/xx/trunk -b http://xx/svn/xx/branches -t http://xx/svn/xx/tags http://xx/svn/xx

同步远程svn到本地svn, 并将svn提交信用户息修改为git提交用户信息

x.map 内容 svn_name = git_name xx@xx.com

git svn fetch -A /xx/x.map

svn标签转git标签

cp -rf .git/refs/remotes/origin/tags/* .git/refs/tags/ rm -rf .git/refs/remotes/origin/tags

svn分支转换git分支

cp -rf .git/refs/remotes/origin/* .git/refs/heads/ rm -rf .git/refs/remotes/origin

推送git服务器

git remote add origin ssh://git@example.com/group/repo.git git push -u origin –all git push origin –tags


## 备份其他仓库
1. git clone --bare url		本地备份远程库
2. git push --mirror url 	本地库备份到远程
3. git remote update --prune本地备份拉取远程

## git 转 Fossil
1. cd git-repo
2. git fast-export --all | fossil import --git name.fossil

## Fossil 转 git
1. git init name
2. cd name-repo
3. fossil export --git ../name.fossil | git fast-import

## git
- git init --bare 初始化git基础库
- git clone 第一次获取库 --recurse-submodules 初始化子模块
- git clone --depth 1 不要历史
- git clone --no-checkout --depth 1 --no-single-branch --progress --config "advice.detachedHead=false"
- git clone --resume xxx 断点续传
- git pull 远程库同步到本地并合并 是git fetch 和 git merge的组合
- git fetch 远程库同步 --unshallow 将指定depth的库及其它分支都拉取到本地
- git push -u origin xxx 本地库同步到远程origin上, -u表示建立跟踪
- git gc 垃圾清理和压缩
- git fsck --full 健康检测
- git status 当前状态信息
- git branch -a 显示所有branch, 带*号的是当前分支 -d删除分支 -dr删除远程分支
- git branch xxx 创建xxx分支
- git checkout xxx 切换到xxx分支
- git checkout -b new_branch 创建新分支
- git merge xxx 将xxx分支的内容合并到当前分支,可能会有合并commit需要提交
- git merge --abort 撤销合并
- git diff 显示修改内容
- git checkout -- path/filename 回复某文件的修改
- git checkout . && git clean -xdf 放弃本地所有修改
- git add path/filename 添加新文件
- git add .git 添加所有文件
- git reset 将已经add但没有commit的文件移除
- git commit -a -m "message"
- git commit --amend -m "xxx" 修改上次的提交(可以正常修改,所有的变动与上次commit合并)
- git diff --cached 查看本地库与远程的差异
- git show 查看最近提交的内容
- git log 查看日志
- git rm 删除文件
- git mv 移动文件
- git clean -nfd 清理工作树
- git blame 查看文件中每一行变动的作者
- git cherry-pick SHA 将某分支的某次特定提交合并到当前分支
- git rebase --abort、--skip 两个分支按时间线来合并
- git stash save pop clear list apply drop --keep-index 临时保存修改
- git init、git remote add -t-f ... git checkout 只克隆某分支
- git checkout --track xxremote/xx 在本地仓库创建同名远程分支并跟踪远程分支
- git revert 复原到老的提交,会产生一个新的提交,是版本变为老的
- git reset --keep 版本回滚, 历史将消失、keep表示保留工作区修改,--hard将彻底丢失修改
- git --git-dir=/.git format-patch -k -l --stdout \| git am -3 -k 将不相干的仓库应用到当前仓库
- git update-index --assume-unchanged 忽略某文件的修改
- git filter-brach --prune-emtpy --subdirectory-filtermaster 将某个文件夹变成新的仓库
- git symbolic-ref HEAD refs/heads/master 设置默认分支
- git rev-parse 显示信息需跟参数如--short HEAD显示当前HEAD的短MD5
- git status 显示当前本地仓库状态 --porcelain显示变化
- git describe --tags 显示最近一次的tag, --always找不到tag就显示HEAD的MD5
- git submodule add 添加子模块
- git submodule update --init --recursive 在git中初始化子模块
- cd submodule目录 git checkout xxxx 指定子模块版本
- git submodule status
- git submodule update
- git submodule deinit && git rm path 删除子模块
- git config --global core.autocrlf true checkout时转换成CRLF,commit时转换回LF.
- git config --global core.autocrlf input checkout时不转换,commit时转换回LF.
- git config --global core.autocrlf false checkout commit均不转换
- git config --global core.safecrlf true 拒绝提交包含混合换行符的文件
- git config --global core.safecrlf false 允许提交包含混合换行符的文件 
- git config --global core.safecrlf warn 提交包含混合换行符的文件时候给出警示
- git config --global core.filemode false 禁止修改文件权限
- git config --global user.name "John Doe"
- git config --global user.email "john@doe.org"
- git config --global color.ui auto
- [url "git@github.com:"] insteadOf = https://github.com/
- git -c 使用指定的key-vale 替换config中的参数
- git ls-tree --full-tree -rt -l hash 显示提交内容

diff.mnemonicprefix=false 比较虚目录是否显示源、当前等符号 core.quotepath=false 是否对目录进行URL转码 credential.helper= 指定用户密码存储


## 彻底删除文件和历史记录
1. git filter-branch --tree-filter 'rm -f ArtQRCode/ffmpeg' HEAD
	git ls-remote
	git update-ref -d refs/original/refs/heads/master
	rm -rf .git/logs
	git reflog expire --expire=now --all
	git gc --prune=now --aggressive
2. git filter-branch --index-filter 'git rm -r --cached --ignore-unmatch ArtQRCode/ffmpeg' HEAD  
    git push origin master --force  
    rm -rf .git/refs/original/  
    git reflog expire --expire=now --all  
    git gc --aggressive --prune=now 
3. git delete remote
   echo 保留的最早提交的Commit Hash > .git/info/grafts
   git filter-branch -- --all
   rm .git/info/grafts
   git update-ref -d refs/original/refs/heads/master
   git reflog expire --expire=now --all
   git gc --prune=now --aggressive

## clone部分代码
1. git init
2. git remote add origin  xxx.git
3. git config core.sparsecheckout true
4. echo "xx/xx" >> .git/info/sparse-checkout
5. git pull origin master 或者 git fetch origin master 可断点续传
      
## CVS转git
1. brew install cvsps
2. export CVSROOT=:pserver:anonymous@cvs.schmorp.de/schmorpforge
3. cvsps login
4. git cvsimport -v -d :pserver:anonymous@cvs.schmorp.de/schmorpforge liev

## 多服务器镜像
- 简单命令
    git clone --mirror   git push --mirror
- 自动创建并同步
    github brew install hub 获取权限token GITHUB_TOKEN
    GitLab brew install gitlab 为了适应CLI 然后生成token和endpoint  GITLAB_TOKEN GITLAB_ENDPOINT
    Bitbucket pip install bitbucket-cli 需要使用ssh登陆

    git 本地库中:
        hub create 创建github同名项目
        gitlab create_project REPO_NAME "{visibility_level: 20}" 公开的
        bb create --protocol=ssh --scm=git --public REPO_NAME

        git remote set-url origin --add https://gitlab.com/USER_NAME/REPO_NAME.git
        git remote set-url origin2 --add https://bitbucket.org/USER_NAME/REPO_NAME.git
        git remote -v 检测设置是否正确

        git pull --all 将同时同步所有的remote

## 同时使用git svn
- 同步svn到git
    - git svn init --prefix=origin/ -T trunk https://svn.webkit.org/repository/webkit
    - git config --replace svn-remote.svn.fetch trunk:refs/remotes/origin/master
    - git config --replace svn-remote.svn.rewriteRoot https://svn.webkit.org/repository/webkit
    - 或者直接编辑 config:
    	[svn-remote "svn"]
        	url = https://svn.webkit.org/repository/webkit
		    fetch = trunk:refs/remotes/origin/master
		    rewriteRoot = https://svn.webkit.org/repository/webkit
   - git svn fetch
   - git fetch && git svn rebase -l 将本地提交易到最上面形成线性
   - git svn fetch 不移动本地提交时间线
   - git svn dcommit 提交会在svn上看到每次提交
   - git rebase -i HEAD〜n 看到n个提交记录
- 使用
    - 每个人必须一个分支,保证git提交是线性的
    - git clone xxx.git
    - git svn clone -s svn://xxx
    - 不要使用git svn 创建svn分支
    - svn 分支应该像trunk一样使用, git 无法合并svn的分支
- 以git作为工作分支,svn没有修改
    - 修改并提交git分支feature
    - git pull origin master 保证git master最新
    - git svn fetch 保证svn最新
    - git checkout feature
    - git svn dcommit 合并feature到svn,命令修改了feature使其历史等同svn
    - git checkout master 准备同步git master
    - git merge 合并svn trunk到master
    - git push origin master 提交到远程
    - git branch -d feature 必须删除,分支已经与远程库不同
    - git push origin --delete feature
- 以git作为工作分支,svn已经修改
    - 修改并提交git分支feature
    - git pull origin master 保证git master最新
    - git svn fetch 保证svn最新
    - git rebase trunk feature 将git分支rebase到svn,修改会自动添加到svn历史后
    - git svn dcommit 提交svn,上一步已经修改了分支,这一步就只提交了
    - git checkout master 准备同步git master
    - git merge feature 合并分支到master
    - git push origin master 提交到远程
    - git branch -d feature 必须删除,分支已经与远程库不同
    - git push origin --delete feature

## git合并
- git merge 会解决冲突并提交一个合并的commit,在时间线上会出现分支线
- git rebase 形成线性提交
    - 在当前分支A rebase B,
    - A分支所有修改历史被另存
    - A历史变为B历史
    - 从当前点一一合并A的历史
    - 合并后的A历史都是新的历史,与以前的不同,因此不要对已经push的历史做rebase

## 修改错误的提交信息

#!/bin/sh

git clone –bare git@gitee.com:nomadli/iplayer.git

pushd iplayer.git git filter-branch –env-filter ‘ NAME=”nomadli” EMAIL=”dzym79@qq.com”

if [ "$GIT_COMMITTER_NAME" != "${NAME}" ] || [ "$GIT_COMMITTER_EMAIL" != "${EMAIL}" ]; then
    export GIT_COMMITTER_NAME="${NAME}"
    export GIT_COMMITTER_EMAIL="${EMAIL}"
fi
if [ "$GIT_AUTHOR_NAME" != "${NAME}" ] || [ "$GIT_AUTHOR_EMAIL" != "${EMAIL}" ]; then
    export GIT_AUTHOR_NAME="${NAME}"
    export GIT_AUTHOR_EMAIL="${EMAIL}"
fi
' --tag-name-filter cat -- --branches --tags

git push --force --tags origin 'refs/heads/*' popd ```

svn简介

  • 两种协议
    • svn://类似json的数据格式 (10:xxxxx xxxx 10000)
    • http(s):// 特殊的ADVWeb格式
    • 两种写走了不同代码路径
    • 总之apach的代码垃圾到吐
  • 两种存储
    • Berkeley DB 数据库中存储数据, 容易锁数据
    • FSFS文件系统存储 推荐
  • 模块
    • svn 客户端
    • svnversion 获取项目的版本号
    • svnlook 检查仓库的工具
    • svnadmin 创建, 调整, 修复仓库的工具
    • mod_dav_svn AVDWeb插件
    • svnserve svn协议服务器程序,可ssh
    • svndumpfilter 过滤仓库转储数据流的程序
    • svnsync 跨越网络对仓库进行增量镜像备份的程序
    • svnrdump 跨越网络对仓库历史进行转储和加载的程序
    • svnmucc 在没有工作副本的情况下, 在一个单独的提交中对多个 仓库执行基于 URL 的操作

git 强制commit用户为已知用户

  • vi .git/hooks/pre-receive
      #!/bin/sh
      zero_commit="0000000000000000000000000000000000000000"
      while read oldsha newsha refname; do
      	echo $refname $oldsha $newsha
        
      	if [ "$newsha" = "$zero_commit" ]; then
          	continue
        	fi
        
      	if [ "$oldsha" = "$zero_commit" ]; then
          	all_commits=$(git rev-list $newsha)
        	else
          	all_commits=`git rev-list $oldsha..$newsha`
        	fi
        
      	for commit in $all_commits; do
          	email=$(git log -1 --pretty=format:%ae $commit)
      		echo "email=" $email
      		if [ "$email" != "dzym79@qq.com" ]; then
      			echo "must use dzym79@qq.com not use " $email
      			exit 1
      		fi
          done
      done
      exit 0
    
  • chmod +x .git/hooks/pre-receive
  • 全局hook: git config –global core.hooksPath xx/xx/hooks
  • gitlab 全局 /opt/gitlab/embedded/service/gitlab-shell/hooks.
  • gitlab gitaly/config.toml [hooks] 设置全局
  • https://docs.gitlab.com/ee/administration/server_hooks.html

git ssh 多账号配置

  • Host 显示用的名称
  • HostName 实际地址或域名
  • AddKeysToAgent [yes, no] 是否将密钥添加到agent中
  • UseKeychain [yes, no] 是否保存到keychain
  • IdentityFile 私钥路径
  • Port 端口默认22
  • User 用户名
  • Match [canonical, final, exec, host, originalhost, user, localuser]
  • AddressFamily [any(default), inet(IPv4), inet6(IPv6)]
  • BatchMode [yes(disable user ui eg. input password), no(default)]
  • BindAddress localip
  • BindInterface local net device
  • CanonicalDomains domain (list domain server list)
  • CanonicalizeFallbackLocal [yes(defualt, not find domain list fail), no]
  • CanonicalizeHostname [no(default, only find), yes(direct server use CanonicalizePermittedCNAMEs.domian), always(proxy or direct)]
  • CanonicalizeMaxDots (hostname max dot count defualt 1, xxx.domian)
  • CanonicalizePermittedCNAMEs (eg *.a.domain)
  • CASignatureAlgorithms ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,ssh-ed25519,rsa-sha2-512,rsa-sha2-256,ssh-rsa (default)
  • CertificateFile ~/.ssh/auto_keys
  • ChallengeResponseAuthentication [yes, no]
  • CheckHostIP [yes, no]
  • HostkeyAlgorithms +ssh-rsa +ssh-dss
  • PubkeyAcceptedAlgorithms +ssh-rsa
  • PreferredAuthentications [publickey, password]
  • PubkeyAcceptedKeyTypes ssh-ed25519* ssh-rsa* ssh-dss* ecdsa-sha2
  • KexAlgorithms diffie-hellman-group1-sha1,diffie-hellman-group14-sha1,diffie-hellman-group-exchange-sha1,diffie-hellman-group-exchange-sha256,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group1-sha1
  • ServerAliveInterval
  • TCPKeepAlive ```sh Host * AddKeysToAgent yes UseKeychain yes IdentityFile /Users/xx/.ssh/eastmoney PreferredAuthentications publickey

Host gerrit HostName a.b.c.e | host.com Port 1234 User xxx Host github_nomadli Hostname github.com User nomadli IdentityFile ~/.ssh/rsa_1 Host github_nomadli2 Hostname github.com User nomadli2 IdentityFile ~/.ssh/rsa_2 ```