Like I said, what do you do when you're merging develop into master and there's a commit that you don't want to merge in develop?
There's things that I want only in develop branch. and eventually there will be time that I have to merge develop into master for deployment. Is there anyway omit those things that I want only in develop branch while merging?
I thought this shouldn't be too hard to resolve but now I think it needs to have more info.
Let's say there's master, develop branch. master is for deployment, and I dont want to commit any un-approved codes to be merged. In develop branch, I committed 10 commits. let's say f(feature)1~10. feature 2,4,7 are not tested yet, but other commits needs to be merged. And there's feature1 which is added only for develop.
For one time I can cherry pick f3,f5,f8,f9,f10. But develop branch will be used forever and next time if I merge, f1,2,4,7 will be merged(even though one can't be sure when to merge 2,4,7 and never wanna merge 1.)
I just want to know what's general solution for this. This shouldn't be new to developers.
Let's say your repo looks like this, and you don't want commit 3.
A - 1 - 2 - 3 - 4 - 5 [develop]
\
B - C [master]
Make a new branch from develop, remove the commit, then merge.
One way to accomplish this is with an interactive rebase.
$ git switch develop
$ git branch tmp-develop
$ git switch tmp-develop
Delete the unwanted commit.
# The ~ means the first parent of commit 3
$ git rebase -i <commit 3>~
3 - 4 - 5 [develop]
/
A - 1 - 2 - 4 - 5 [tmp-develop]
\
B - C [master]
Then merge and delete tmp-develop.
$ git switch master
$ git merge tmp-develop
$ git branch -d tmp-develop
3 - 4 - 5 [develop]
/
A - 1 - 2 - 4 - 5
\ \
B - C --------- M [master]
However, if you need to do this on a regular basis, this is indicative of a problem with your development process.
UPDATE ...and there is.
To be more specific, the feature I mentioned is a device simulator, which periodically generates dummy telemetry data and puts data into database. I need this to be on dev branch to work, and there's no need for a simulator in master.
There might not be a need for the simulator, but there's also no need to remove it.
Normally, all your test infrastructure is kept in master (now called "main"). This allows anyone to develop and test your code and simplifies the whole development process. The code is released in a separate process to package the code. There you may strip the test code if it is a binary package. If it is an Open Source project, often the whole source tree is packaged, tests and all.
Alternatively, make the device simulator a test dependency. Either your dependency manager installs it, or it must be installed manually like any other 3rd party dependency such as a database. You might be tempted by submodules, but they're not a replacement for dependency management and are often more trouble than they're worth.
Often projects will provide multiple config files for multiple environments: dev, test, and production. These are all checked in. They contain no secrets and no per-developer configuration like usernames.
Secrets (API keys or passwords) and detailed configuration (usernames, hostnames) are put in environment variables so they are never saved to a disk and accidentally committed. Most deployment pipeline systems have ways to store these secrets securely, or you can use something like Vault.
Let's say there's master, develop branch. master is for deployment, and I dont want to commit any un-approved codes to be merged. In develop branch, I committed 10 commits. let's say f(feature)1~10. feature 2,4,7 are not tested yet, but other commits needs to be merged. And there's feature1 which is added only for develop.
This is a problem. While you can shuffle commits around, it rapidly gets complicated and error prone.
Nothing should be shared which is not fully tested. Nobody should be committing directly to the shared branch; they risk sharing broken code (complicating everyone's work) or blocking a release.
Unless you really need one, there is no separate development branch, there is just main. Main is always kept at high quality and ready for release.
All work should be done in branches. Units of work should be small so their branches are short and merged as quickly as possible. No work should be merged until it is tested and ready for release. This is the feature branch workflow. It's very simple and it works well and it's the basic technique leading to more advanced ones.
See Continuous integration vs. delivery vs. deployment for more about keeping your code high quality and always ready for release.