简体   繁体   中英

git clone : by default shallow or not?

My initial understanding of git was it being meant (at least initially) to be a decentralised VCS (allowing for example fully-offline work and even cloning a repo from another offline repo ...).

This was, still per my initial understanding, the reason why the terminology was "cloning" when retrieving a repository : because we were actually getting it all - a full copy of it (allowing a full offline work or for someone else to clone it some more etc.).

But then I realised that it was not the case: sometimes I am working on my master that is up to date; then switch to another branch and I would expect that to be up to date as well, but when I git fetch (or git pull) I get new stuff (that is not necessarily that new).

So was my initial understanding wrong? is actually a clone not a real clone? is it actually a shallow one? what are the default settings to git clone? the official documentation only states that --depth "creates a shallow clone"; should I understand it lets me choose the depth (or should I say shallowness?) of the said clone? or that it creates a shallow clone as opposed to a deep one being created without the option?

When you clone a git repo, you get a full copy of the master branch, and retrieve all the metadata for other branches at the time of cloning (which is stored in your repo's .git dir). Git uses this metadata to construct the branches when you check them out / switch between them locally. Branches will be out of date if someone has pushed to a remote branch since you cloned the repository, or since the last time you fetched data from the remote .

You need to be online in order to perform a fetch, and each branch is (by default) managed separately. So, if you perform a "pull" in "master", no other branches will be updated automatically - though git will (again, by default) pull the metadata for all other branches so you can switch between them and perform merges as you need to.

Fetched branch commits are dormant until you specify what you want to do with them whilst working in that branch . The reason for this, is that you may have different / working copies of local branches that you do not want to merge with the remote changes just yet - so you must do that manually when you're ready to do so. Imagine a scenario where you have the following branches:

  • master
  • feature/my-feature

You're currently working feature/my-feature with another developer - both of you are pushing code regularly and collaborating. You're then asked to work a bug fix for LIVE; in this scenario you would stash or commit your changes in feature/my-feature , possibly push (if the changes are ready for the other developer to work with), switch to master , do a pull and create another bug fix branch to fix the LIVE issue - you wouldn't want your feature/my-feature code to be overwritten... you'd want to control that manually, when YOU are ready for the remote branch changes.

A "pull" is a combination of a "fetch" and a "merge". The "fetch" pulls branch metadata from the server, and the "merge" takes the current remote tracked branch commits, and merges them into your local branch.

A "shallow clone" in git still gets you the latest snapshot of code, but does not clone the entire history graph. That's the only difference - it has nothing to do with branches. The depth parameter allows you to specify how many commits you should pull back for each branch. Personally, I've never needed to use it other than when I'm pulling back repositories on CI / CD servers.

Git is very different from VCS's such as TFS, and not just because you have to be online all the time. It is extremely flexible - and allows you as a developer to be extremely flexible in the way you work (as long as you chose the right branching strategy for your needs) - but it does - unfortunately - require some re-learning, especially when it comes to the terminology ( git checkout doesn't pull code from the remote, for example - it just switches between your local branches).

Git clone is not shallow by default for the branch you are pulling, however it won't pull all commits presented in remote branches unless you checkout them. If you want to clone for backup or mirror purposes then you should use --bare option. Bare clone pulls everything for a total copy. Note that bare repositories can not be used directly unless pointed from another clone, perhaps at least a local one.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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