The most troubling feature new developers to DVCS need to realize is about the publication process:
- you can import (fetch/pull) whatever remote repo you need
- you can publish (push) to any (bare) repo you want
From that, you can respect a few rules to make your questions easier:
Now:
Workflows / branching models:
each workflow is there to support a release management process, and that is tailored for each project.
What I can add to the workflow you mention is: each developer should not create a feature branch, only a "current dev" branch, because the truth is: the developer often doesn't know what exactly his/her branch will produce: one feature, several (because it ended up being too complex a feature), none (because not ready in time for release), another feature (because the original one had "morphed"),...
Only an "integrator" should established official feature branches on a "central" repo, which can then be fetched by developers to rebase/merge the part of their work that fits that feature.
Merging vs rebasing (tangled vs sequential history):
I like my answer you mention ("Workflow description for git usage for in-house development")
I am looking for a natural workflow:
for fixes, it can help associating each fix with a ticket from a bug tracking, which helps the developer remember where (i.e. on which branch, i.e. a dedicated branch "for fixes") he/she should commit such modifications.
Then hooks can help protect a central repo against pushes from non-validated bug-fixes or from branches from which one shouldn't push. (no specific solution here, all this need to be adapted to your environment)
How to avoid creating merge conflicts (due to cherry-pick)?
As stated by Jakub Narębski in his answer, cherry-picking should be reserved for rare situations where it is required.
If your setup involves a lot of cherry-picking (i.e. "it is not rare"), then something is off.
Would applying the same commit in revert (how to do this?)
git revert
should take care of that, but that is not ideal.
How to decompose into topical branches?
As long as a branch as not yet been pushed everywhere, a developer should reorganize its history of commits (once he/she finally see the development takes a more definitive and stable shape) into:
- several branches if needed (one by clear identified feature)
- a coherent set of commits within one branch (see Trimming Git Checkins)
Proper procedures like code review and graduating ?
Integration branches (in a dedicated integration) repo can help the developer to:
- rebase his/her development on top of that remote integration branch (pull --rebase)
- solve locally
- push the development to that repo
- check with the integrator that doesn't result in a mess ;)
git stash push -p -m "my commit message"
-p
let's you select the hunks that should be stashed; whole files can be selected as well.
You'll be prompted with a few actions for each hunk:
y - stash this hunk
n - do not stash this hunk
q - quit; do not stash this hunk or any of the remaining ones
a - stash this hunk and all later hunks in the file
d - do not stash this hunk or any of the later hunks in the file
g - select a hunk to go to
/ - search for a hunk matching the given regex
j - leave this hunk undecided, see next undecided hunk
J - leave this hunk undecided, see next hunk
k - leave this hunk undecided, see previous undecided hunk
K - leave this hunk undecided, see previous hunk
s - split the current hunk into smaller hunks
e - manually edit the current hunk
? - print help
Best Answer
Migrations rollback are possible and usually handled automatically by django.
Considering the following model:
If you run
python manage.py makemigrations myapp
, it will generate the initial migration script. You can then runpython manage.py migrate myapp 0001
to apply this initial migration.If after that you add a field to your model:
Then regenerate a new migration, and apply it, you can still go back to the initial state. Just run
python manage.py migrate myapp 0001
and the ORM will go backward, removing the new field.It's more tricky when you deal with data migrations, because you have to write the forward and backward code. Considering an empty migration created via
python manage.py makemigrations myapp --empty
, you'll end up with something like:For pure data-loading migrations, you usually don't need the backward migration. But when you alter the schema and update existing rows,
(like converting all values in a column to slug), you'll generally have to write the backward step.
In our team, we try to avoid working on the same models at the same time to avoid collision. If it is not possible, and two migration with the same number (e.g 0002) are created, you can still rename one of them to change the order in will they will be applied (also remember to update the
dependencies
attribute on the migration class to your new order).If you end up working on the same model fields at the same time in different features, you'll still be in trouble, but it may means these features are related and should be handled together in a single branch.
For the git-hooks part, it's probably possible to write something, Assuming your are on branch
mybranch
and want to check out another feature branchmyfeature
:mybranch_database_state.txt
myfeature
branch migrations, if anymybranch
, you reapply your previous database state by looking to the dump file.However, it seems a bit hackish to me, and it would probably be really difficult to handle properly all scenarios: rebasing, merging, cherry-picking, etc.
Handling the migrations conflicts when they occurs seems easier to me.