简体   繁体   English

用私有远程存储库重写git历史记录

[英]Rewriting git history with a private remote repository

I use a private remote repository for two main reasons, backup my work in progress when I travel from the office to home or synchronise code between two development machines. 我使用私有远程存储库的原因主要有两个,当我从办公室到家时备份正在进行的工作或在两个开发机之间同步代码。

I have recently started playing with git (coming from hg) and I like the idea of rewriting history. 我最近开始玩git(来自hg),我喜欢重写历史记录的想法。 What I found recently is if I do the following 我最近发现的是,如果我执行以下操作

  • # do work # 做工作
  • git commit git提交
  • git push git推
  • # Fix a little problem with the last commit #修复最后一次提交的一些问题
  • git commit --amend git commit-修改
  • git push git推

There is a conflict with the remote. 与遥控器发生冲突。 I need to pull, merge and push again. 我需要再次拉,合并和推动。

  1. Is there a way to mirror my local changes to the remote repository? 有没有办法将本地更改镜像到远程存储库?
  2. On my second machine, how do I pull those mirror the remote into my local (preferably without a full clone again) 在我的第二台计算机上,如何将那些镜像远程对象拉入本地(最好再没有完整的克隆)

I know that I'm the only one using it, so I know that no one else will have to deal with a changing history. 我知道我是唯一使用它的人,所以我知道没有其他人需要处理不断变化的历史。

You can force a push with git push -f remote-name branch-name then just git pull on the second machine. 您可以使用git push -f remote-name branch-name强制执行推送,然后在第二台计算机上执行git pull If there is a conflict you can force the pull with git fetch --all followed by git reset --hard remote-name/branch-name . 如果发生冲突,您可以使用git fetch --all紧跟git reset --hard remote-name/branch-name强制拉git fetch --all You'd better be sure what you're doing though, rewriting history as part of your regular workflow isn't recommended. 您最好确定自己在做什么, 不建议将历史记录重写为常规工作流程的一部分。

I meant to say forcing pushes and pulls regularly isn't recommended. 我的意思是不建议定期强制推拉。

You can also execute a 您也可以执行

   git reset HEAD^ --hard 

on the remote repository and redo git push after performing a git pull form the local repository. 在远程存储库上执行,并在从本地存储库执行git pull之后重做git push。 I think it is somewhat less dangerous, though more involved, than the git push --force because you only need to validate that you are rewinding the exact right thing and you can always keep a safe copy on the remote repository with 我认为与git push --force相比,它虽然危险性更高,但涉及程度更小,因为您只需要验证倒带的正确内容,并且始终可以使用以下命令将安全副本保留在远程存储库中:

    git checkout -b safe-copy-old-branch-name

before doing everything which not only keeps an original of the previous "intentions" behind the commits but also keeps the exact same (orignal) SHA1. 在做所有事情之前,不仅要在提交之后保留先前的“意图”的原始内容,而且还要保持完全相同(原始)的SHA1。

You can literally set up the "exchange / backup" remote as a mirror (a bare clone that takes "force" style ref updates, rather than requiring that some or all ref updates be fast-forwards). 您可以从字面上将“交换/备份”远程设置为镜像(一个裸克隆,它使用“强制”样式的参考更新,而不是要求某些或所有参考更新都是快进的)。

"Normal" clones are set up to do force-updates of refs/remotes/* : take a look at .git/config (or use git config --get remote.origin.fetch ) and you'll see that the fetch refspec for origin is: 设置了“普通”克隆以强制更新refs/remotes/* :看一下.git/config (或使用git config --get remote.origin.fetch ),您将看到获取refspec origin是:

+refs/heads/*:refs/remotes/origin/*

The plus sign means "force", ie, "don't require a fast forward". 加号表示“强制”,即“不需要快进”。 Hence, when you git fetch origin , whatever commit SHA1 that (eg) origin's refs/heads/master names, becomes your local refs/remotes/origin/master , no matter what commit SHA1 your refs/remotes/origin/master used to point-to. 因此,当您git fetch origin ,无论(例如)起源的refs/heads/master名称的任何SHA1提交都成为您的本地refs/remotes/origin/master ,无论您的refs/remotes/origin/master指向哪个提交SHA1 -至。 This is generally safe (and hence the default even for "ordinary" clones) because these "remote branch" SHA1-pointer names wind up in refs/remotes/ rather than refs/heads , ie, it does not affect your local repo's branch name-space in any way. 这通常是安全的(因此对于“普通”克隆也是默认的),因为这些“远程分支” SHA1指针名称以refs/remotes/而不是refs/heads ,即,它不会影响本地存储库的分支名称。 -空间以任何方式。

When you use git push -f —or specify a push refspec starting with a + , which means the same for push as for fetch—this tells the remote that it should also allow non-fast-forwards. 当您使用git push -f -或指定以+开头的push refspec,这与push和fetch的含义相同-这告诉遥控器它也应允许非快进。 (That is, it tells the—for want of a better phrase—"built in hook" to allow fast forwards. Other git hooks on the remote to which you are pushing can still reject the change.) This is generally not safe because it affects the remote repo's name-space: you're updating its refs/heads/master , not something like refs/pushes/JohnsMachineAtHome/master . (也就是说,它告诉了换一个更好的词组“建于勾”,让快进的想。遥控器上的其他git的钩子到你是推还是可以拒绝变更)。这通常是可靠,因为它影响远程仓库的名称空间:您正在更新 refs/heads/master ,而不是refs/pushes/JohnsMachineAtHome/master But if you know what you're doing, and don't make mistakes (or at least not often :-) ), it's OK after all. 但是,如果您知道自己在做什么,并且不犯错误(或者至少不经常犯错,:-)),那还是可以的。

Remember also that every commit in git is reasonably sticky as long as there is some reference (eg, the reflog) pointing to it, so in that particular sense it's safe to force-push and force-fetch as long as you commit first. 还要记住,只要有一些引用(例如reflog)指向git,每次在git中的提交都是合理的粘性,因此从特定的意义上讲,只要先提交,就可以安全地强制推送和强制获取。 (As in, if you goof up, you might have to ssh in to work/home from home/work and poke around in the reflog to find a commit you dropped on your mirror.) Be aware that bare clones (including bare mirror clones) don't keep all that much in the way of reflogs (there is some data kept, especially with core.logAllRefUpdates set; see git config docs) since the updates they get are en-masse at push or fetch time. (例如,如果您犯规,您可能必须在家中上班/上班,然后在reflog中四处查找才能找到您在镜像上提交的提交。)请注意,裸克隆(包括裸镜像克隆) )不要让所有的东西在reflogs的方式( 一些数据保存,尤其是core.logAllRefUpdates设置;参阅混帐配置文件),因为他们得到了更新EN-集体在推动或提取时间。

See also these git config options: 另请参阅以下git config选项:

  remote.<name>.push The default set of "refspec" for git-push(1). See git-push(1). remote.<name>.mirror If true, pushing to this remote will automatically behave as if the --mirror option was given on the command line. 

you can work on a temporary branch and rebase it before merging it with the master branch. 您可以在一个临时分支上工作,并在与master分支合并之前对其重新设置基础。 Rebasing (--> 'git rebase -i master') allows you to reorder and edit commits. 重置(->'git rebase -i master')允许您重新排序和编辑提交。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM