[RFC/PATCH] WIP: add deprecation & experimental process/interface

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is the WIP start of a deprecation & experimental interface to
git. The goal is to formalize the workflow around deprecating
features, or around introducing new experimental features.

This is much more idea than code at the moment, but included is an
example showing how :/ might be deprecated[1] (let's not discuss /if/
we should do that here, this is just an example).

The plan, subject to RFC feedback is to:

 * Add a new config variable `core.version`. E.g. `core.version =
   2.14.0` With this the user can specify that they'd like
   new/experimental features introduced in that version (and below),
   as well as immediately getting new deprecations added in that
   version as errors.

   This is similar to perl's "use v<VERSION>".

 * Add a deprecated() function to to mark deprecated features.

   This will emit an arbitrary warning about the use of a feature once
   per-process (via static variable). The call needs to declare in
   what version the deprecation was added, and in what version it
   should start warning/dying.

   This sets up a well-defined path to deprecation, and allows users &
   packagers to plan upgrades, and e.g. set `core.version` to N
   versions in the future to see what would start warning/dying in
   those releases.

 * TODO: Add an experimental() function to mark experimental features.

   Depending on parameters & config an experimental feature might be
   off by default unless `core.use_experimental_<NAME> = true`, or it
   might warn unless that config is set.

 * TODO: Add new documentation (gitdeprecated.txt /
   gitexperimental.txt) aiming to exhaustively list deprecated &
   experimental features, and when it's planned that each of those
   will be fully removed or start/stop warning when used.

 * TODO: Subject to RFC feedback add a gitpolicy.txt similar to
   "perlpolicy" (mainly
   http://perldoc.perl.org/perlpolicy.html#BACKWARD-COMPATIBILITY-AND-DEPRECATION)
   describing how this deprecation/experimental process works. See
   also [2].

1. https://public-inbox.org/git/CACBZZX6K7ppVB0qYah76_+pjTKjsco3rHT0xRyKtF2H1dS4k_w@xxxxxxxxxxxxxx/
2. https://public-inbox.org/git/CACBZZX5oVKGZLKgS4aF0=XXtHO67ynS+zxSopDN9ErJGzV9n-A@xxxxxxxxxxxxxx/

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@xxxxxxxxx>
---
 GIT-VERSION-GEN |  1 +
 Makefile        |  5 +++++
 deprecate.c     | 34 ++++++++++++++++++++++++++++++++++
 deprecate.h     |  7 +++++++
 sha1_name.c     |  3 +++
 5 files changed, 50 insertions(+)
 create mode 100644 deprecate.c
 create mode 100644 deprecate.h

diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN
index 4f94fc7574..c76bbedf86 100755
--- a/GIT-VERSION-GEN
+++ b/GIT-VERSION-GEN
@@ -37,4 +37,5 @@ fi
 test "$VN" = "$VC" || {
 	echo >&2 "GIT_VERSION = $VN"
 	echo "GIT_VERSION = $VN" >$GVF
+	echo "GIT_VERSION_INT = $(echo $VN | sed -e 's/^\([0-9]*\)\.\([0-9]*\)\..*/\1\2/')" >>$GVF
 }
diff --git a/Makefile b/Makefile
index e35542e631..1614b2b067 100644
--- a/Makefile
+++ b/Makefile
@@ -739,6 +739,7 @@ LIB_OBJS += csum-file.o
 LIB_OBJS += ctype.o
 LIB_OBJS += date.o
 LIB_OBJS += decorate.o
+LIB_OBJS += deprecate.o
 LIB_OBJS += diffcore-break.o
 LIB_OBJS += diffcore-delta.o
 LIB_OBJS += diffcore-order.o
@@ -1793,6 +1794,10 @@ version.sp version.s version.o: EXTRA_CPPFLAGS = \
 	'-DGIT_VERSION="$(GIT_VERSION)"' \
 	'-DGIT_USER_AGENT=$(GIT_USER_AGENT_CQ_SQ)'
 
+deprecate.sp deprecate.s deprecate.o: GIT-VERSION-FILE
+deprecate.sp deprecate.s deprecate.o: EXTRA_CPPFLAGS = \
+	'-DGIT_VERSION_INT="$(GIT_VERSION_INT)"'
+
 $(BUILT_INS): git$X
 	$(QUIET_BUILT_IN)$(RM) $@ && \
 	ln $< $@ 2>/dev/null || \
diff --git a/deprecate.c b/deprecate.c
new file mode 100644
index 0000000000..035a1adea1
--- /dev/null
+++ b/deprecate.c
@@ -0,0 +1,34 @@
+#include "cache.h"
+#include "deprecate.h"
+
+void deprecate(int *state, const char *message,
+		int dep_at, int warn_at, int die_at, int remove_at)
+{
+	/*
+	 * If we're going to warn let's do it once per-process, not
+	 * spew lots of warnings in a loop.
+	 */
+	if (*state == 1)
+		return;
+	else
+		*state = 1;
+
+	if (remove_at >= GIT_VERSION_INT) {
+		die("BUG: The '%s' deprecation should be removed in this release!");
+	} else if (die_at >= GIT_VERSION_INT) {
+		die(_("Deprecation error: %s"), message);
+	} else if (warn_at >= GIT_VERSION_INT) {
+		warning(_("Deprecation warning: %s"), message);
+	} else if (1) {
+		/*
+		 * TODO: Instead of `if 1` we should check a
+		 * core.version variable here.
+		 *
+		 * I.e. if set to core.version=2.13 the user is opting
+		 * in to get deprecations set at dep_at right away,
+		 * and also perhaps experimental features from a
+		 * sister experimental() interface.
+		 */
+		die(_("Early bird deprecation error: %s"), message);
+	}
+}
diff --git a/deprecate.h b/deprecate.h
new file mode 100644
index 0000000000..7d565ef0ed
--- /dev/null
+++ b/deprecate.h
@@ -0,0 +1,7 @@
+#ifndef DEPRECATE_H
+#define DEPRECATE_H
+
+extern void deprecate(int *state, const char *message,
+		      int dep_at, int warn_at, int die_at, int remove_at);
+
+#endif
diff --git a/sha1_name.c b/sha1_name.c
index 35c1e2a9e3..b381c39bd4 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -1505,6 +1505,7 @@ static int get_sha1_with_context_1(const char *name,
 	int namelen = strlen(name);
 	const char *cp;
 	int only_to_die = flags & GET_SHA1_ONLY_TO_DIE;
+	static int dep_state = 0;
 
 	if (only_to_die)
 		flags |= GET_SHA1_QUIETLY;
@@ -1527,6 +1528,8 @@ static int get_sha1_with_context_1(const char *name,
 		char *new_path = NULL;
 		int pos;
 		if (!only_to_die && namelen > 2 && name[1] == '/') {
+			deprecate(&dep_state, _(":/<text> is deprecated. Use ^{/<text>} instead!"),
+				  213, 214, 215, 216);
 			struct commit_list *list = NULL;
 
 			for_each_ref(handle_one_ref, &list);
-- 
2.13.0.303.g4ebf302169




[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]