Home > database >  Is there a file or config or settings for ignoring files/folders in the remote repository and preven
Is there a file or config or settings for ignoring files/folders in the remote repository and preven

Time:09-21

I wanted to try this out but don't know if it's possible. Usually, to prevent files/folders from being tracked by git and also pushed to the remote from the local, you would add a .gitignore file - gitHub doc.

I'm asking for the other way round. Is there a file, config or settings for ignoring files/folders in the remote repository and preventing download to local?

1st paragraph edited thanks to @IMSoP's response.

CodePudding user response:

No: as already noted, Git works on a commit-by-commit basis, and when you use git clone or git fetch,1 you obtain the commits from the other Git. Those commits contain the files that they contain, as a snapshot.

Yes: once you have commits from some other Git repository in your repository, you can extract individual files from these commits. There's no automatic way to do this, but you can set up your own scripts. Be careful about it because some Git operations will read an entire commit and populate your working tree with lots of unwanted files.

Your best bet is probably to clone the repository somewhere else and then bring over the files of interest.


1Although the code is built into the clone command directly, git clone uses git fetch, so to some extent this is redundant.

CodePudding user response:

This isn't a standard workflow, so there's no convenience commands for it. You can get Git to do this, it's even fairly easy once you've got the "extensible dag of immutable snapshots, with labels on" mantra down cold, but all the convenience commands are set up to expect a full history in reach so you generally have to avoid them and replace them with the (very few) core commands each invokes for you.

Just to be clear: see the Git docs for the commands I'm using, and git help revisions for the revision syntax like @{U} aka @{u} aka @{upstream}`. Turns out you can do everything a dvcs needs to do with an extensible dag of immutable snapshots, with labels on, if you maintain an index of the pieces in any current snapshot being viewed or constructed. Imagine Gary Oldman yelling "everything!". E v e r y t h i n g Git does is extending, analyzing, and schlepping around bits of that dag. The structure itself is bone stupid. What you can do with it, is not.

Let's take the aosp platform base repo and say you want to look at the core directory, the full history is big enough to be painful for casual cloning and so if you're exploring you might want to see just part of it.

That much is almost cookie-cutter easy:

git clone -n --filter=tree:0 https://github.com/aosp-mirror/platform_frameworks_base.git
cd !$:t:r    # history expansion for `cd platform_frameworks_base`
git read-tree -um @:core

and you have now fetched the barest sketch of the entire history, and only the latest copy of only the core directory.

If you just wanted to look, you're done¹. For patch work on what you've got checked out, all the usual convenience commands that deal with commits will need replacing by short core-command "no no do just this part really" sequences, like the read-tree above instead of the usual checkout the -n switch told git clone not to do.

Just to have something concrete to talk about, let's say you've got some doc fixes to do that only touch this directory, or we could imagine that this really is a separable history that just hasn't been officially separated for whatever reason, and you want to carry patches on it. Whatever.

First up: let's do this on a mystuff branch:

git checkout -b mystuff      # new name for the current work
git branch -u master@{u}     # tracking whatever the master branch tracks

Next, git commit is a convenience command that, for your convenience, prints a summary of what changed from the parent commit, which is good to have when you're composing a commit message but means it'll fetch whatever parts of the current commit you just went to some small effort not to fetch. But you really don't want to have to avoid git commit forever, so let's tell git what we're up to just this first time:

git reset --soft $(git commit-tree -p @ -m mystuff @:core)
git tag mystuff-base

and after further git commits can proceed normally, everything the convenience command expects is all set up.

You can push your cut branch anywhere, but when people merge with it they'll need to specify the -Xsubtree (or -Xsubtree=core, Git's good at figuring this out but you can just tell it what subtree you mean) merge option, because as I said this is not a standard workflow and Git by default won't spend any effort looking for possible hoist/splice points like this.

If you want to bring your own branch up to date with the latest master tip, an ordinary git merge will look at that latest master tip and the merge base. The whole of both commits. Which you don't want. To avoid that,

git fetch    # honors the filtering set up by that `git clone` above
git merge $(git commit-tree -p mystuff-base -p @{u} -m 'core slice' @{u}:core)
git tag -f mystuff-base

and that's really all there is to it: you now know enough to fetch, merge and push just the content you're working with, and only the parts you really need to look at.


¹ If you were just looking at the one subdirectory and that's all, you could even add --depth=1 to the clone to get not even a sketch of the full history

  • Related