I frequently find myself changing a single variable in my project within Git to connect to a different server while on the Development branch (in JavaScript, so I can't use preprocessor defines).
Is there some way in Git that I can conditionally use one file or another depending on what branch I'm on?
I can't just commit that change with the different URL specified as doing so would leave it in my commit history, and if I go back to that version later on Master after it has been merged, it will have the development server URL.
No, there isn't, but this is a well-solved problem.
You have a few options:
config.example
file which lists all the configuration options that need to be specified, and provides sane defaults for development.config.example
to the real config filename, and add real values.gitignore
.setup.sh
script, which copies config.example
to the real config's location, and populates it with variables for the local environmentAs an example, you might have a JavaScript application which needs to know where its database is, and reads this information from config/database.json
. You might use something like this:
// config/database.example.json
DATABASE = {
"host": "localhost",
"user": "#TODO",
"pass": "#TODO",
}
To get running in development, you would copy this file to config/database.json
, and fill in the values appropriate to your dev environment.
In production, you'd have a config/database.json
that contained production values, but was not version controlled.
The repo would have config/database.json
in its .gitignore
.
config.development
and config.production
etcIf there is anything remotely sensitive in your config file, such as AWS keys or any form of password, you should use the first option - store the configuration option's name, but not its value, and require users to supply their own credentials, obtained through secure channels outside of version control.
Note that condition include config is coming, starting with Git 2.13 (Q2 2017).
The only condition supported as of now is the project name, not the hostname.
In your case, that would work if each branch is checked out in its own folder (with git worktree
: see "Multiple working directories with Git").
See commit 86f9515, commit 4aad2f1 (05 Apr 2017) by Nguyễn Thái Ngọc Duy (pclouds
).
(Merged by Junio C Hamano -- gitster
-- in commit a2e2c04, 24 Apr 2017)
config
: add conditional includeSometimes a set of repositories want to share configuration settings among themselves that are distinct from other such sets of repositories.
A user may work on two projects, each of which have multiple repositories, and use oneuser.email
for one project while using another for the other.Setting
$GIT_DIR/.config
works, but if the penalty of forgetting to update$GIT_DIR/.config
is high (especially when you end up cloning often), it may not be the best way to go.
Having the settings in~/.gitconfig
, which would work for just one set of repositories, would not well in such a situation.
Having separate${HOME}s
may add more problems than it solves.Extend the
include.path
mechanism that lets a config file include another config file, so that the inclusion can be done only when some conditions hold.
Then~/.gitconfig
can say "includeconfig-project-A
only when working onproject-A
" for eachproject A
the user works on.In this patch, the only supported grouping is based on
$GIT_DIR
(in absolute path), so you would need to group repositories by directory, or something like that to take advantage of it.We already have
include.path
for unconditional includes.
This patch goes withincludeIf.<condition>.path
to make it clearer that a condition is required.
The new config has the same backward compatibility approach asinclude.path
: older git versions that don't understandincludeIf
will simply ignore them.
Git 2.14 (Q3 2017) clarifies the documentation.
See commit ce933eb, commit a076df2, commit 994cd6c, commit 9d71d94 (11 May 2017) by Jeff King (peff
).
(Merged by Junio C Hamano -- gitster
-- in commit ed98060, 29 May 2017)
The documentation now reads and includes:
Includes
The
include
andincludeIf
sections allow you to include config directives from another source. These sections behave identically to each other with the exception thatincludeIf
sections may be ignored if their condition does not evaluate to true; see "Conditional includes" below.
The same Git 2.14 reinforce that feature.
See commit 0624c63 (16 May 2017) by Ævar Arnfjörð Bjarmason (avar
).
(Merged by Junio C Hamano -- gitster
-- in commit b784d0b, 30 May 2017)
The recently introduced "
[includeIf "gitdir:$dir"] path=...
" mechanism has further been taught to take symlinks into account.The directory "
$dir
" specified in "gitdir:$dir
" may be a symlink to a real location, not something that$(getcwd)
may return.
In such a case, a realpath of "$dir
" is compared with the real path of the current repository to determine if the contents from the named path should be included.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With