Django migrations files for large project in git (Best Practice) - django

I work with a team in Django project, in the local git with same database.
we found that there was a lot of problems with django migrations specially when the team is large.
So we decided to make databases for each developer, sometimes the developer delete them migrations files to solve some problems with migrations.
we get a lot of the conflict in Django migrations files, we decided to add migrations files to gitignore.
Then all the work become more smoothly. but we get some problems we lost the git history for migrations files, this gives problems at updating the project versions from the specific git tag. Also, it will delete the migrations files at every time we make "checkout" in git.
I suggested the following but I did find its answers
make migrations files tracked by local repository and ignored in the remote repository.
Any one have forced this issue?

The question as to whether migration files should be committed is pretty well answered by the linked possible duplicate. This answer is not about that: it's about your proposed solution.
The idea of making some file "tracked" by some specific repository is somewhat nonsensical. In Git, a file is tracked if and only if that file is currently in Git's index. Hence we need to address this question:
When is a file in Git's index?
The simple answer is simple—too simple—and confusing and unhelpful: a file is in Git's index when that file is in Git's index. Files go in and out of Git's index all the time, though.
The purpose of Git's index is to help you build the next commit you will make. The files that are in Git's index right now—and this changes from one point in time to the next—are the files that will be in your next commit.
The git add command will, under the right conditions, copy a file from your working tree—the files you can see and work on / with are in your working tree—to Git's index. If there was already some file with that name in Git's index, that copy is kicked out of the index, so that the working tree copy can be copied in. If there was no file with that name in Git's index, the file is now added to Git's index. This copy, once copied into Git's index, remains there, in Git's index, even if you change or remove the working tree copy: these are separate copies.1
Under other conditions, git add will do nothing, or will even remove the index copy of a file. Using git rm --cached will remove the index copy of a file, and using git rm will remove both the index copy and the working tree copy. So you have several Git commands that can affect the index copy: git add, which can replace the index copy or remove it, and git rm, which can remove it.
The conditions under which git add does each of these things are a little complicated, but meant to be simple to use:
git add of an all-new file adds it to Git's index;
git add of an updated-in-working-tree file kicks out the old copy and adds the new one instead; and
git add of a removed file—one that you removed from the working tree, but without using git rm to do that—removes the index copy.
So git add "means" make the index copy match the working tree copy.
The condition under which git add does nothing (except maybe emit a warning that it's not adding the file) occurs when the file (a) isn't already in the index and (b) is listed in a .gitignore. Condition (b) means do not add the file even if I tell you to add it. This does not affect a file that is in the index—see condition (a)—because, well, the file is in the index. However it may have gotten there, it's there now, so git add will update it to match the working tree.
But there is one more key way that files get into Git's index, and that is: whenever you extract (git checkout or git switch) an entire commit, Git reads the commit into the index as part of extracting the commit's files to your working tree. What this means is that checking out a commit that has a migration file will put that file into Git's index. The commits control which files are in the index.
The commits are what two Git repositories share, when you connect them up with git fetch, git pull, and/or git push. A commit, once made, can never be changed in any way. So if someone—anyone—has ever committed some migration file, and you git checkout that commit, that file appears in both your working tree and Git's index. If you then switch from that commit, to some other commit where the file is not in the commit, Git will remove that file from both Git's index and your working tree.
In short, once committed, a file is there forever. Moving from a commit that has the file, to one that doesn't have the file, means delete the file. Moving from a commit that doesn't have the file, to one that does, means add the file. This is not optional. It always happens, every time. The file goes into Git's index or comes out of Git's index; it is now tracked or untracked correspondingly.
You can, having switched to or from such a commit, subsequently alter Git's index using git add and/or git rm. This will change the tracked-ness of the file. But switching to or from another commit updates Git's index, changing the tracked-ness of files.
1The index copy is, however, stored in Git's compressed and de-duplicated format, all ready to go into the next commit. This means that if you use various Git debugging facilities to locate the internal object and dump out its bytes, they won't match the working tree copy's bytes. It's a lossless compression scheme though, so the bytes are all there. It's just that they may take up little or even no disk space, due to the compression and de-duplication tricks Git uses.
The bottom line
The conclusion you should take from all of this is that "tracked-ness" of a file is not up to the repository. It's up to the individual commit. Each commit has some files. Extract that commit extracts those files, which are now tracked. Each commit doesn't have some other files. Extracting that commit will remove those files if they are sitting around in your working tree because they were extracted from a commit that did have them.
This is all controlled by the contents of Git's index, so it's possible—but extremely painful—to check out some commit, getting a bunch of files that are tracked, then use git rm --cached to remove some of those files from Git's index so that Git forgets that they came out of that commit. Switching to some other commit that lacks those files will leave those files in your working tree. But doing this repeatedly is extremely error prone. Don't do this! You will regret it.

Related

Why has this needed folder become a submodule?

I have a folder which has all the main code in it but its been created on Github as a submodule and I don't know how to change it or why it was created that way by Git?
Also I'm making new branches and pushing them and every time I do the same "branch" (it seems) is being pushed so the folder is staying the same.
git branch new
git add .
git commit -m "blah"
git remote add origin new
I take it that this code is wrong to make a completely new branch commit?
I've tried numerous ways and seem to be going down a dead end constantly. Is there something wrong with my commits or adds?

SVN tracking changes across files

I am working on a legacy C++ project where there are many classes in a single file and some files end up being 8k+ lines. I am planning on moving some of these classes to separate files. The project uses SVN. I am wondering if SVN can track the history of such change because I may not do the refactoring if it can't.
As an example, I have old.cpp with 3 classes A B C. I want to refactor this into A.cpp B.cpp C.cpp. If I select history of C.cpp, I want to see the class used to be in old.cpp and all the changes to C in old.cpp.
I have never tried it with single files (only with complete folders, which is essentially branching), but in TortoiseSVN you can drag-n-drop the file using right mouse button. When you drop the file (within the same working folder) in displayed context menu select "SVN copy and rename versioned item here". After that (and other changes) commit the working copy.
Another option is to do the same thing, but from repository browser. The difference from previous option is that here each operation is automatically a new revision. I prefer the first option.
After the file is copied edit it to remove the extraneous content. Using the first option you can do it in the same revision as the copying.
Since your project in SVN - you always will be able to return to the original version.
I strongly recommend writing unit tests before the change, so you can track the sanity of the program after each change.
I have an experience in the past with such a change, here how I did it:
Create a separate branch in SVN
Checkout the source from this branch
For each class do the next steps:
Move the class to separate (new) file without changing it. Since the creation you will be able to control each change in SVN
Commit the change to SVN - this way you know that nothing changed in the contents of the file.
Make the necessary changes to the newly created file.
Run unit tests
Commit the change

Is it safe to clone a git repository into its own .git directory?

I recently put my website under Git version control. I'm using git-ftp to upload files, and I've set it up so that the master branch is the content that should be on the server, and the live branch is the content that actually is on the server. I need to make this distinction since I sometimes develop where I don't have an Internet connection, and therefore can't upload right away. Therefore, in order to upload, I do: git checkout live;git merge master;git ftp push; I'd like to automate this process and not lose the rest of working directory state. In the future I'm also going to set up automatic backups of several files which will be ftp'ed down and committed to the live branch.
In order to do all of this, I'm going to need another clone that will only be used by automated processes, and will always have a clean working directory. The obvious place to put it, since it will never need to be looked at, is inside the .git directory of the main repository. That way, I don't have a clone floating off somewhere else in my filesystem, it stays hidden, and it's obvious that it's part of the internals and shouldn't be poked about with. If this works well, I may even submit a patch to fix git-ftp issue #180 with this method.
However, I'm not sure if it's a good idea to put random things inside the .git folder--I can't find any documentation anywhere on what the side effects may be.
A .git directory seems to ignore completely any extra elements, so adding a git repo directly in .git should work.
That wouldn't work if you added your nested repo in a sub-directory like, for example, .git/refs (see Git Internals - Git References)
Note that you could also have that git repo anywhere in your current git repo, as a directory named, for instance, .ftprepo (a name beginning with a dot, which should be hidden by default)
I found the answer by mistake while looking for something else!
According to https://www.kernel.org/pub/software/scm/git/docs/#_file_directory_structure, "Higher level SCMs may provide and manage additional information in the $GIT_DIR". This appears to mean that additional info can be stored in .git without causing problems, including, presumably, another clone of the repository.

Git tells me my changes haven't been committed, even though they have been?

I was trying to clean up my directory by deleting no longer relevant files. Since then, whenever I try to push, I get the error "Your local changes to the following files would be overwritten by merge: [list of some files I tried deleting]. Please commit or stash them before you can merge" which is odd because all my other file deletions were committed successfully.
EDIT: I renamed my local copy and cloned the repo again, and discovered that the changes I made /were/ going through, but for some reason the web app itself hasn't been reflecting those changes. I tried clearing my browser's cache and viewing the website on other browsers, but those changes just don't appear anywhere except in the files I cloned, which baffles me completely.
Is there any explanation for why the web app is not displaying the most recently updated files?
I still get this error, if it sheds any light:
"Your local changes to the following file would be overwritten by merge:
static/css/newcss.css
Please, commit your changes or stash them before you can merge.
Despite the fact that I have not altered that file in any way since cloning it.
(Also note, I'm using Django for this web app)
EDIT EDIT: So I guess to close this question, the updating of the site was just taking a long time to process (like, two weeks long).
When i use GIT, i usually get this kind of strange errors.
Have you try this: Git telling me to pull, then commit, then pull?
Are you certain you committed your changes? Run this:
git diff
If something comes up, it means there are changes in your working directory that don't match your last commit, e.g., that is the change that needs to be committed.
Try committing the file that changed:
git add myfile.txt
git commit myfile.txt -m "Committing my file"

git patch ignoring white space diffs c++

The only thing I care about is C++ file. (Don't worry about binary files, text, etc ... you can assume taht everything is C++ code_).
I have these branches:
* dev
master
Now, I can to create a new branch "magic", where branch magic is equiv to "dev" (in terms of C++ code generated), but minimizes useless whiteline diffs (like inserting extra newlines) from master.
Is this possible?
Thanks!
Your question isn't completely clear to me. I think you want the new branch to contain series of commits that are "equivalent" to the ones in dev but don't contain unnecessary whitespace changes.
The simplest way to do this is with git rebase --interactive. This allows you to edit a series of commits manually. You can get the hash of the first ("root") commit with git rev-list HEAD | tail -n 1. If you want to edit the first commit as well, that's more difficult but there's a SO answer for that.
git checkout dev
git checkout -b magic
git rebase --interactive $(git rev-list HEAD | tail -n 1)
This brings up an editor on the list of commits in forward chronological order. You change pick to edit on the commits that you wish to change. git will then pause before processing each of these commits, allowing you to modify it with git commit --amend and then continue the rebase with git rebase --continue. You could of course run a script to clean up the files rather than editing them manually. If you want to do this based on the differences from the previous commit you would need to use something like git cat-file blob HEAD^:filename to fetch the previous revision, or use git diff HEAD^ filename.
If you want to automate the whole process then you can use git filter-branch --tree-filter script. Look at the man page for git-filter-branch for details.
If you want to prevent future commits from containing whitespace errors, you can set up a pre-commit hook to disallow them.
Once you're happy with the new branch magic you can use it to replace dev:
git branch -m dev dev-old
git branch -m magic dev
However, note that this might cause problems for people who already have a copy of dev in their own repos. It would then be better to do a merge instead.
git diff --ignore-space-change ...
You could try setting up a post-merge hook which will:
only do anything if the current branch is magic
remove all whitelines of *.cpp files
make a new commit (since a post-merge hook cannot directly affect the outcome of git merge)