Configuring (existing) VS proj & gitignore

Hello - a brief introduction of myself: I’m a old coder trying to manage a git/lab project, but my git experience is limited to clone - pull - checkout - add - commit - push and rebase. that’s all I almost know.
I’ve given a mantainer role of an existing but empty gitlab repository, and have to upload a working VS proj to start versioning/tracking it vía git. This VS project contains a bunch of not-need-to-be-tracked files and folders (exists a plenty of gitignore templates) BUT such files need to exist in the repository to be downloaded at the very first clone, coz if don’t, the proj doesn’t even run (don’t know why, but it happens).

What do I need:

  1. any of the repository’s users be able to clone master/develop branch containing all of those needed files.
  2. this user create his working branch; then, the user add a gitignore file and do his work.
  3. when this user push the branch, changes I’ll see on gitlab to be merged should be only those “hand-touched” by the user - no single one present in gitignore.

What did I do so far:

  1. clone the empty master branch locally.
  2. copy the whole proj files to tacked directory.
  3. git add + commit + push (it’s how I’m filling up the gitlab’s empty project)
  4. checkout -b to a new branch.
  5. even before running VSstudio I create a gitignore file at root-project level, then:
    $ git rm -r --cached + git add . + commit -m ‘Update .gitignore’
  6. run VS and add a //comment on an existing file.
  7. perform git status and yes, there’s just the hand-touched file marked as modified
    (despite knowing there’re more changed files coz being runned the IDE).
  8. git add + commit + git push origin mybranch.
  9. assign to myself the merge request.

What do I see on gitlab’s changes tab:
all of the offending files present in gitignore, aside the hand-changed file and the new gitignore file are
present to be merged.

What do I expect to see:
just the hand-changed file
btw: there’s also a new gitignore file - guess I also have to exlcude it off the merge…

Questions:
Am I working the right way / show I achieve my goal in a different way? which is it?
In case I’m taking an acceptable approach: am I forgetting any command?
(guess if I get my goal, every newbranch lacking of those files would be “self un-testeable” : if I checkout to that branch I won’t run coz lacking of needed files – it’s an issue…)

EDIT
guess I’m understanding what’s gitlab telling to me:
what I see in the Changes tab, is the ABSENT of ignored files in myNewBranch (so gitignore is working) compared side-by-side to master, in where such files still remains (and need to continue being so).
Now I realize that I released the user of the hassle of non-wanted changes by using gitignore, but he “push the problem” up to me, coz now if I accept merge request, master branch will copy newBranch content, losing those needed files.
Should I now exclude by hand each of this files of the merge process -peventing’em of dissapearing on master? (dont’ even know if gitlab will let me do so)

Is there an easiest way to handle all of this situation?
END EDIT

Any (detailed) help will be truly appreciate.
Thanks in advance,

Hi,

before I dig into the specific question, here is a general suggestion from providing trainings on Git and GitLab: Try to create the .gitignore file by yourself, and commit these changes to the master branch once, in the same manner as you import the source code once.

Also, I’d recommend to avoid different states of .gitignore entries in various Git branches. After all, branches should be merged at some point.

For the current state, I believe you now have:

  • The master branch with all files
  • A secondary branch where .gitignore has been added and specific files are ignored
  • Your question is now how to bring the master branch uptodate?

The output of git status and git log in these branches would certainly help :slight_smile:

Cheers,
Michael

Very thanks for answering dnsmichi,
My question is not how to update master branch – that’ll be reached by the merge process I guess.
The issue is a more “wide” situation …which I’ll try to syntetize in a single question:
How to tell git -thru gitignore- to serve the whole project at clone request, but to ignore changes present in gitignore’s files, instead of marking the absent (interpreted as deletions by now) of such files within gitignore? (hope to be clear enough)

I already tryied to add a gitignore file (one of the offered on gitlab by Add new file -
Templates…), but I did so after uploading the source, and the result of this was that when performing the clone process of master, those files didn’t download, and the proj went unrunnable.

-Yes, I noticed you’re recommending to add a gitignore file within the project for the very first upload/filling of gitlab repo and I’ll try your recipe out asap, but in the meanwhile I’ll tell U what is do working to me so far (maybe this’ll give U a clue of what’s going on / what do I need):
<> I upload the initial seed/master to gitlab containing no gitignore at all.
<> I clone it locally
<> Inmediatlly (avoiding modifying it by just opening the IDE) I perform:

git checkout -b mytestbranch

<> then I open IDE and change just one file of this new branch.
<> after that I do git status and see about 20 files (!) marked in red where just one of’em is wich I’ve modified by hand.
so I

git add myModifiedFile

Now my file turned to green, and offending ones remains in red, then:

git restore .

so all of the red files dissapear, and now yes

git commit -m “This is almost driving me crazy” && git push origin mytestbranch

<> finally I go to gitlab and assign the merge request to myself, and once there I go to changes tab and … voilá!!! there’s just one file marked as modified to be merged!
This is exactly the result I’m expecting to achieve and tying to automate

Seems that -instead of a .gitignore, what I need is a “.gitrestore” (in case of such a thing exists)

I really appretiate your help, hoping not to bore you

Well, I’ve followed your recipe, but result is exactly the same as I got in all of the previous runs.

Being .gitignore’s logic to handle it content as inexistent files, I guess this is not the approach I have to work on.

What I need is to find a way to previously mark certain files as not-needed-to-be-locally-updated (coz they’ll change on every local compilation) despite of YES such files have to exist in repo and have to be downloaded on each clone request .

The only (hard) way I found so far to handle this issue is by

git add each’n_every_modified_by_hand_file && git restore .

…which leads to all team’s coders remember exactly which files did they modify, coz to perform just

git add .

is not efficient anymore -but yet possible.

Of course coders won’t find this procedure natural nor comfortable, just like I do (that’s why I jokingly mentioned a sort of “.gitrestore” file) …the point remains I cannot see any other way to deal with this.

Any idea will be trully appreciated.

Best regards,
Jp.

Hi,

you are writing a lot, and some of your thoughts are confusing - to me. That’s fine, I’m only a little worried about not getting to know where you are at and how I can help you.

So, you are saying that your Git repository now contains files which never should have been added/committed before. Is that assumption correct?

Is there any chance you can share the repository content, e.g. on gitlab.com and I can have a look? Or you’ll do a screenshot of the repository and visually mark the things you’d like to remove/add/change?

Cheers,
Michael

Hi Michael, thanks 4 taking your time on this … I promise try to keep brief and clear as I can :wink:

So, you are saying that your Git repository now contains files which never should have been added/committed before. Is that assumption correct?

Nopes, kinda of inverse situation: I do need a bunch of files to be present on repo and to be downloaded on every clone request (local compiler needs’em), and have no problem achieving this - just avoiding any gitignore file.
Such (lot of) files will suffer local changes which are machine-dependant and meaningless to the remote repo, that’s why submitting’em to remote is just a bandwidth waste -and a source of confussion to developers who see lot of changed files which they never touched by hand.

Is there any chance you can share the repository content, e.g. on gitlab.com and I can have a look?

I would have to ask premissions to do so, and this would be embarrassing to me, but I tell which files are:
every windows form’s project have a BIN/ and a OBJ/ directories, containing binaries and object code. It’s supposed such files are machine-dependant and can be ignored (that’s why are present in every gitignore template) but in this my particular case, if such folders are absent, project do not compile nor run.
so:

  1. need some files to be present in remote repo and to be downloaded during clone (done)
  2. this files will “automatically change” locally, and need such changes not to be tacked just to avoid pushing’em up to repo. (here is the issue). This doesn’t mean to gitignore them coz if so, files will dissapear from repo and I need’em up there.

So what I do need is to automatically ignore changes, not to ignore files.

Hope to be clear enough
cheers,
Jp.

Hi,

ah, it is getting more clear.

  • .gitignore is here to ignore binary assembled files in BIN/ and OBJ/ directories.
  • Windows compiler needs some of them as dependency.

Empty directories in Git

If I get that correctly, you only need the directories being present, but not the content in there. If that is correct, there is a trick to add empty directories to Git:

  • Add a hidden file called .gitkeep into the directory (starting with a dot means hidden on Linux)
  • Ensure that this file is added and committed to your Git repository

Example which should work with Powershell:

echo $null >> OBJ/.gitkeep
echo $null >> BIN/.gitkeep
git add OBJ/.gitkeep BIN/.gitkeep
git commit -m "Add BIN and OBJ build directories"
git push

Directories with partial content

If you instead need some specific file patterns in there, you need to adjust the .gitignore file

# ignore files and sub dirs in the /OBJ directory
/OBJ/*
# but do not ignore specific files, e.g. config.xml
!/OBJ/config.xml

Similar pattern for BIN.

Cheers,
Michael

Thanks 4 answering so fast!


BREAKING: Guess we have a point with this your last answer … I will experiment on that.
Despite of it, I won’t erease all of I just wrote, so it lecture maybe drop a little bit more of light over my issue


well, noup … I need the dir and it contents … what I do need is not to track it changes.

Let me draw a shorty explanation:

On remote repo I have (and need):

BIN/fileNeverTouchedByHand.txt <- file having just a number “1” in it.

once locally cloned and opended the ide, this local file changes:

BIN/fileNeverTouchedByHand.txt <- now contents number “2”

then, on git status:

Changes not staged for commit:
(use “git add …” to update what will be committed)
(use “git restore …” to discard changes in working directory)

This situation is annoying for coders, and force them to run git restore before every commit.

Is there a way to tell git kinda: Listen pal, fileNeverTouchedByHand will change… but want you to always track it as unchanged ? So, it won’t appear on git status, avoiding confussions.


PD: I’ll play with that .gitkeep method

Sadly confirm it won’t work.
Keeping just the empty directories is not enough. Seems VS need its contents as ‘references’ (as compiler’s errors say).

So, back to the “gitrestore” concept … exist anyway to tell git to ignore changes of existing files (instead of ignore the files by themselves)?

Just 4 items to dramatize the need:

  • Yup, there is a complete and filled OBJ directory on seed/gitlab repo;
  • Yup, all of the repo content (including OBJ dir) downloads on clone request;
  • Noup! the locally modified OBJ directory won’t get uploaded for merge on Push, because this directory is locally marked as ignore changes (as git uploads only modified files, doesn’t it?)
  • Yup!! remote repo preserves it original OBJdir for each future clone request.

Really hope to find a way to make this possible.
Best regards,
Jp

Hi,

my answers are not always fast, having lots of things on my plate :wink: I have been thinking about your question, but there doesn’t seem to be a solution for that specific case of

  • add a file once
  • ignore and do not track its changes later

I’ve tried that with .gitignore and force add once, it immediately starts to track things.

➜  ~ cd dev/gitlab
➜  gitlab mkdir git-playground
➜  gitlab cd git-playground
➜  git-playground git init
Initialized empty Git repository in /Users/mfriedrich/dev/gitlab/git-playground/.git/
➜  git-playground git:(master) mkdir BIN
➜  git-playground git:(master) echo "/BIN" >> .gitignore
➜  git-playground git:(master) ✗ git add .gitignore
➜  git-playground git:(master) ✗ git commit -av -m "Add BIN to gitignore"
[master (root-commit) 77d8ebb] Add BIN to gitignore
/BIN
 1 file changed, 1 insertion(+)
 create mode 100644 .gitignore
➜  git-playground git:(master) git status
On branch master
nothing to commit, working tree clean
➜  git-playground git:(master) touch BIN/config.xml
➜  git-playground git:(master) git status
On branch master
nothing to commit, working tree clean
➜  git-playground git:(master) git add --force BIN/config.xml
/BIN
➜  git-playground git:(master) ✗ git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	new file:   BIN/config.xml

➜  git-playground git:(master) ✗ git commit -v -m "Add BIN/config.xml once"
[master 4877a12] Add BIN/config.xml once
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 BIN/config.xml
➜  git-playground git:(master) echo "Tanuki here" >> BIN/config.xml
➜  git-playground git:(master) ✗ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
	modified:   BIN/config.xml

no changes added to commit (use "git add" and/or "git commit -a")

Meh.

The internet suggests to work with update-index commands but they may cause faulty behaviour.

Specifically this quote from the docs worries me:

In general, Git does not provide a way to ignore changes to tracked files, so alternate solutions are recommended.

That being said, would it be reasonable to ask your developers to run a cleanup script after compiling things? We used to do that within a Makefile in the past - make clean could for example run git checkout BIN/modified.file and reset its state.

Cheers,
Michael

Hi, Michael,
I saw you were working on git cli trying to make it works and your effort is thruly appretiated.

I already found a solution, but before telling it wanna say that all of this request was because I thought a gitRestore approach would be faster than a traditional solution which imply lots of tyiping, ending up spending much more time of tyiping and deleting and uploading many many times, just trying to achieve that easier way (aside of finding out if sort of approach does exist - now we know the answer)

The traditional fix I found was to track which exact files (and which not) were being modified on each run within those certain directories, just to write’em down before deleting them and checking out if app remains usable.
Once checked app ran, despite of such files were deleted (regardless during runtime compiler re-create’em) I built a very personalized gitignore, containing about ~25 paths to exact files - no single directory nor wildcard-syntax was included on it.


Detail of my procedure - can skip this:
Now yes, for the last time: went to gitlab repo to un-protect develop, set master back as default and delete repo’s develop branch. Back in local I checkout to master, git branch -D myBranch develop, deleted everything but .git/, then add+commit+push -yes, an empty dir- to master. Once checked gitlab’s master branch was existing but empty, went back again to local and rm -fr the entire project directory, ran git clone (getting that emtpy master), built a new seed with the new gitignore and offending files already deleted and inmediatly push this to remote repo, even before running it in IDE. Then, moved to another dir to prefrorm a git clone, expecting to download a clean yet runnable project. Runned it on IDE and checked there were no new adds to track - despite knowing VS have created 'em…


Now I can say it’s working, having a seed which won’t track files created by the IDE.

I have a last question - last by now, of course :smiley: :
working on gitlab I noticed a button labeled delete branch, which I used to delete develop, but not to delete master (doing it from local, as described on my procedure).
I’m wonder what will happen if I use this button to choose delete Master, being it the only remaining branch. Is it possible? would the repo get unusable because the lack of any branch? (remember I’m the mantainer of the repo, not the owner).

Well, I don’t bother you anymore.
I send you my best regards, expressing my gratitude for all of your time and help.
Cheers,
JuanP.

Hi,

no worries on bothering me. You are trying your best to explain everything in detail, appreciate that.

Just one more tip for the future - keep the initial problem description short and simple to allow people who just have a minute or two to chime in, stay, think and maybe answer. Reading a long text takes quite a while, and modern times are always in a rush :slight_smile:

To my knowledge, default branches cannot be deleted. If you are not certain about, the easiest way is to go to GitLab.com and create a new test project. Tick initialize the project with a README on creation which auto-creates the first commit then. Next, try to delete the master branch.

You can also dive into protected branches and limit their usage to prevent further deletion.

Cheers,
Michael