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

备份其他仓库

  1. git clone –bare url 本地备份远程库
  2. git push –mirror url 本地库备份到远程

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 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
  • 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 ```