Git远程服务器仓库文件存储
我很快就会开发一些 iPhone/iPad 应用程序,并正在考虑使用 Git 作为我的版本控制系统。在过去的项目中(但不是基于 iOS 的)我使用过 SVN。我转向 Git 的主要决定是去中心化的结构。
我将使用远程服务器作为中央 Git 存储库(很可能是 Atlassian 的 bitbucket)。我还没有设置这个,但与此同时我一直在本地测试 Git。
我已经阅读了许多初学者资源,现在对基础知识有了相当好的掌握,但有一点我需要确认我是否正确理解。
在下面的示例中,我在 Mac 上使用本地版本的 Git。
我创建了一个名为 git_test 的本地 git 存储库。在此存储库中,我有两个名为 file1 和 file2 的虚拟文件。我知道这是我的工作目录,其中包含我的实际文件(而不是 blob)。
我还了解远程服务器上的中央存储库应该是裸露的,并且不包含工作目录的实际文件。
假设我有两个用户(用户 A 和用户 B)具有相同的本地存储库。
用户A
- 修改文件1
- 提交文件1
- 执行到远程存储库的推送
用户B
- 修改文件2
- 提交 file2
- 执行对远程存储库的推送
我是否正确地说新的 blob 已上传到远程存储库中的 .git/objects 目录?
然后,当用户 A 和用户 B 在其本地系统上执行拉取命令时,实际文件(而不是 Blob)将更新为新 Blob 的内容。这是正确的吗?
抱歉问了这么长的问题。我只是希望一切都有意义。
I will be working on a number of iPhone/iPad apps soon and am looking at using Git as my version control system. In past projects (but not iOS based) I have used SVN. My main decision for switching to Git is the de-centralised structure.
I will be using a remote server as a central Git repository (most likely Atlassian's bitbucket). I haven't set this up yet, but in the meantime I have been testing Git locally.
I've read through a number of beginner resources and now have a fairly good grasp of the basics but there is one thing I need to confirm I understand properly.
In my example below I am using a local version of Git on my Mac.
I have created a local git repository called git_test. In this repository I have two dummy files called file1 and file2. I understand that this is my working directory which contains my actual files (and not blobs).
I also understand that the central repository on a remote server should be bare and not contain the actual files of the working directory.
Let's assume that I have two users (User A and User B) with identical local repositories.
User A
- Modifies file1
- Commits file1
- Executes a push to the remote repository
User B
- Modifies file2
- Commits file2
- Executes a push to the remote repository
Am I correct in saying that the new blobs are uploaded into the .git/objects directory in the remote repository?
Then, when User A and User B execute a pull command on their local systems the actual file and not the blob is updated with the contents of the new blob. Is this correct?
Sorry for the long-winded question. I just hope everything makes sense.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您无需过多担心裸存储库内的 blob。更好理解的是,每个存储库都是由提交对象组成,这些对象包含提交到该存储库时的确切文件结构。
在您的示例中,用户 A 在本地生成 commitA,用户 B 在本地生成 commitB,它们都基于裸存储库上的 master,该存储库将指向提交对象(例如)commitBase。这意味着它们都有 commitBase 的父级。
当 A 推送时,他将其 commitA 推送到裸存储库,这将主分支指针向上移动到 commitA。有关 file1 的所有信息都位于提交对象 commitA 内(以及有关文件结构其余部分的信息)。
在 B 推送之前,他必须首先将 commitA 的更改获取到他的存储库中,因为远程主分支指针不再指向 commitBase。在他与远程提交对象和分支指针同步之前,他无法推送。因此,当他将 commitA 对象放入他的存储库时,他将获取 fileA 作为其中的一部分,如果他执行拉取或变基操作,该文件将出现在他的文件系统中,但只会将提交对象放入他的存储库中(而不是将文件放入他的存储库中)他的工作目录)如果他进行了提取。 Fetch 只是使用新的提交对象在内部更新 git,而不更改您自己的主分支指针。在合并/变基时,git 必须对工作目录中的文件做出一些决定,例如公共文件是否可以轻松合并,或者新文件是否可以直接放入磁盘,或者文件是否太大冲突,您必须手动解决文件中的冲突。
在您的简单示例中,您没有冲突,因此您可以重新设置基点并使您的 commitA 成为 commitA2 并具有 commitB 的父级,或者合并并保留 commitA 对象的父级作为 commitBase,但生成一个新的 commitM 对象,该对象是合并 B 和 A。
git 如何在 3 个存储库中的任何一个的 .git/objects 目录中内部表示这一点在这一点上是无关紧要的。它可能会压缩和移动内容,以最大化其所有这些对象的数据库,但在尝试了解文件的提交对象如何工作时,这并不是我担心的事情。
You don't need to worry too much about the blobs inside the bare repository. What is better to understand is that every repository is made up of commit objects that contain the exact file structure at the time of the commit to that repository.
In your example, user A locally generates a commitA, user B locally generates commitB, they were both based off master on the bare repositiory which would have pointed to a commit object (say) commitBase. Which means both of them have a parent of commitBase.
When A pushes, he pushes his commitA to the bare repository, which moves the master branch pointer up to commitA. All the information about file1 is inside the commit object commitA (along with information about the rest of the file structure).
Before B pushes, he must get the changes for commitA into his repo first because the remote master branch pointer no longer points to commitBase. He can't push until he's in sync with the remote on the commit objects and branch pointers. Thus when he gets the commitA object into his repo, he's going to get fileA as part of that, which will appear in his filesystem if he does a pull or rebase, but will only get the commit object into his repository (not the file into his working directory) if he does a fetch. Fetch just updates git internally with the new commit objects without changing your own master branch pointer. It's at the point of merge/rebasing that git is going to have to make some decisions about the files in the working directory, like if common files have easy merging, or if new files can be just put onto disk, or if there's too big a conflict and you'll have to manually resolve the conflicts in the files.
In your simple example, you have no clash, so you would either rebase and make your commitA become commitA2 and have a parent of commitB, or merge and keep your commitA object's parent as commitBase, but generate a new commitM object that is the result of merging B and A.
How git internally represents this in its .git/objects dir in any of the 3 repositories is kind of irrelevant at this point. It might be compressing and moving stuff around to maximise its database of all those objects as it likes, but it's not something i've ever worried about when trying to understand how the commit objects to files work.
当您推送到远程存储库时,如果您的本地存储库落后于远程存储库,它会拒绝它
不确定这是否回答了您的问题
这确保您不会尝试更改已更改的文件 - 它会强制您拉取事先进行最新更改
此外,当您拉取本地存储库时,是的,实际文件发生了变化 - 在 git 存储库中,我相信它会创建一个新的 diff 文件 iirc 但我可能会弄错,我所知道的是它实际上并没有远程覆盖文件
When you push to the remote repo it will deny it if your local repo is behind to remote repo
Not sure if that answers your question
This makes sure that you do not try to change a file that was already changed - it forces you to pull the newest changes beforehand
Also when you pull to your local repo yes the actual file changes - in the git repo I believe it creates a new diff file iirc but I could be mistaken, all I know is that it does not actually overwrite the files remotely