From baf8ab225a4090c0599d307270aeb360e358c92d Mon Sep 17 00:00:00 2001 From: aassuied-ps <123543888+aassuied-ps@users.noreply.github.com> Date: Fri, 22 Aug 2025 19:00:33 +0200 Subject: [PATCH 1/6] Initiate commit blog post First part 'What is a commit?' done. Upcoming updates will include when to commit and how to. --- site/posts/how-to-commit/index.qmd | 65 ++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 site/posts/how-to-commit/index.qmd diff --git a/site/posts/how-to-commit/index.qmd b/site/posts/how-to-commit/index.qmd new file mode 100644 index 0000000..2db0b90 --- /dev/null +++ b/site/posts/how-to-commit/index.qmd @@ -0,0 +1,65 @@ +--- +title: "How to write a good commit message" +subtitle: "Keep easy trackchanges history for your project" +author: "alex" +date: "2025-08-22" +categories: [git, version-control, revision-history] +# image: "thumb.png" +toc: TRUE +toc-title: "Table of contents" +toc-depth: 5 +--- + +This blog post covers the topic of Git commits, how it is working, and how to use them in an efficient way. + +## What is a commit? + +A commit is a snapshot of a Git repository at a specific time that will show all the changes made to the content of the repository. + +A commit will capture the followings: + +- The author's name or ID of the commit + +- The list of modified files and the comparison with the files (if any) of the source branch + +- The date/time of the commit + +- A message that will clearly describe (and possibly detail) the reason of the files' update. + +Each commit is associated to a specific identifier code. + +## Benefits of commits + +Despite the fact that making commit is mandatory when working on a Git repository to update files, there are a lot of benefits in using Git commits. + +### Keep clear history of changes + +Commonly, each program has a header that contains a *"Revision history"* part. Git commits can easily replace this part because it contains the main information of a classic revision history message (author, date and reason for change), associated to the full files comparisons, such as a before/after view. + +All the changes of a single commit are stored in the same place. It means if you work on a single task that request to modify several programs, you can summarize the changes within one message. You do not need to open each separated files one by one to look at what was done, when, and by who. + +::: callout-tip +#### Consolidate all commits of a branch + +Even with several commits, you can have a clear view of all the changes when merging to the source branch. +::: + +### Backup save + +As Git is a version control software, and each commit is a snapshot done at a current state, it is easy to go back to a previous version of a branch using commit IDs. + +::: callout-caution +#### Under construction + +Not finished. +::: + +## When to commit? + +### Commit one file at a time or several? + +::: callout-caution +### Under construction + +Under construction +::: From d3cc5558a9a7bc93521198c9f0fd082c9903ade8 Mon Sep 17 00:00:00 2001 From: aassuied-ps <123543888+aassuied-ps@users.noreply.github.com> Date: Fri, 29 Aug 2025 12:41:31 +0200 Subject: [PATCH 2/6] Add "when to commit?" part to index.qmd --- site/posts/how-to-commit/index.qmd | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/site/posts/how-to-commit/index.qmd b/site/posts/how-to-commit/index.qmd index 2db0b90..df5b426 100644 --- a/site/posts/how-to-commit/index.qmd +++ b/site/posts/how-to-commit/index.qmd @@ -49,17 +49,28 @@ Even with several commits, you can have a clear view of all the changes when mer As Git is a version control software, and each commit is a snapshot done at a current state, it is easy to go back to a previous version of a branch using commit IDs. ::: callout-caution -#### Under construction +#### Need feedbacks - hash -Not finished. +I think talking about `git checkout` and `git reset` here is not useful. Maybe another blog post could be interesting. What do you think? ::: ## When to commit? ### Commit one file at a time or several? +The choice depends on the context and what you want to show. + +If the task or feature to add is isolated to a single file, one commit message done at the end of the update can be easily readable and integrated to the history trackchange. + +In the case of a debugging task over several files, one commit message per file could also be useful, or when there is a need to track the evolution of a specific dataset. + +When a change on a program affects the behavior of other programs that also needs to be updated, one commit for all the modifications can be done. Also when you decide to modify both a program and the associated documentation. + ::: callout-caution -### Under construction +#### Need feedbacks. -Under construction +Need feedbacks. ::: + +## How to write a good commit message + From 791278756bc4a16b9eed473ba3e25af79b0c5188 Mon Sep 17 00:00:00 2001 From: aassuied-ps <123543888+aassuied-ps@users.noreply.github.com> Date: Wed, 3 Sep 2025 08:56:18 +0200 Subject: [PATCH 3/6] Add part how to commit Explains why good commits are important and how to make a good commit title and body detail --- .../index/execute-results/html.json | 11 + .../site_libs/clipboard/clipboard.min.js | 7 + .../site_libs/quarto-listing/list.min.js | 2 + .../quarto-listing/quarto-listing.js | 243 ++++++++++++++++++ site/posts/how-to-commit/index.qmd | 53 +++- 5 files changed, 315 insertions(+), 1 deletion(-) create mode 100644 site/_freeze/posts/how-to-commit/index/execute-results/html.json create mode 100644 site/_freeze/site_libs/clipboard/clipboard.min.js create mode 100644 site/_freeze/site_libs/quarto-listing/list.min.js create mode 100644 site/_freeze/site_libs/quarto-listing/quarto-listing.js diff --git a/site/_freeze/posts/how-to-commit/index/execute-results/html.json b/site/_freeze/posts/how-to-commit/index/execute-results/html.json new file mode 100644 index 0000000..80c2bde --- /dev/null +++ b/site/_freeze/posts/how-to-commit/index/execute-results/html.json @@ -0,0 +1,11 @@ +{ + "hash": "ccf061c41b5f1bf5bea49a93e2685063", + "result": { + "markdown": "---\ntitle: \"How to write a good commit message\"\nsubtitle: \"Keep easy trackchanges history for your project\"\nauthor: \"alex\"\ndate: \"2025-08-22\"\ncategories: [git, version-control, revision-history]\n# image: \"thumb.png\"\ntoc: TRUE\ntoc-title: \"Table of contents\"\ntoc-depth: 5\n---\n\nThis blog post covers the topic of Git commits, how it is working, and how to use them in an efficient way.\n\n## What is a commit?\n\nA commit is a snapshot of a Git repository at a specific time that will show all the changes made to the content of the repository.\n\nA commit will capture the followings:\n\n- The author's name or ID of the commit\n\n- The list of modified files and the comparison with the files (if any) of the source branch\n\n- The date/time of the commit\n\n- A message that will clearly describe (and possibly detail) the reason of the files' update.\n\nEach commit is associated to a specific identifier code.\n\n## Benefits of commits\n\nDespite the fact that making commit is mandatory when working on a Git repository to update files, there are a lot of benefits in using Git commits.\n\n### Keep clear history of changes\n\nCommonly, each program has a header that contains a *\"Revision history\"* part. Git commits can easily replace this part because it contains the main information of a classic revision history message (author, date and reason for change), associated to the full files comparisons, such as a before/after view.\n\nAll the changes of a single commit are stored in the same place. It means if you work on a single task that request to modify several programs, you can summarize the changes within one message. You do not need to open each separated files one by one to look at what was done, when, and by who.\n\n::: callout-tip\n#### Consolidate all commits of a branch\n\nEven with several commits, you can have a clear view of all the changes when merging to the source branch.\n:::\n\n### Backup save\n\nAs Git is a version control software, and each commit is a snapshot done at a current state, it is easy to go back to a previous version of a branch using commit IDs.\n\n::: callout-caution\n#### Need feedbacks - hash\n\nI think talking about `git checkout` and `git reset` here is not useful. Maybe another blog post could be interesting. What do you think?\n:::\n\n## When to commit?\n\n### Commit one file at a time or several?\n\nThe choice depends on the context and what you want to show. Generally, each commit should be dedicated to a single purpose.\n\nIf the task or feature to add is isolated to a single file, one commit message done at the end of the update can be easily readable and integrated to the history trackchange.\n\nIn the case of a debugging task over several files, one commit message per file could also be useful, or when there is a need to track the evolution of a specific dataset.\n\nWhen a change on a program affects the behavior of other programs that also needs to be updated, one commit for all the modifications can be done. Also when you decide to modify both a program and the associated documentation.\n\n::: callout-caution\n#### Need feedbacks.\n\nNeed feedbacks.\n:::\n\n## How to write a good commit message\n\nAs a history tracking, a commit message should be concise and clearly explain **what** was done and **why**.\n\n### Title\n\nThe title should be very short (around 50 characters) and explain **what was done** on which file(s) (if relevant).\n\nStarting the title with a verb is very useful to explain what was done, for instance:\n\n::: note \n`Add TRTEMFL in adae.R`\n:::\n\n\n\n```{bash}\nAdd TRTEMFL in adae.R\n```\n\n\nA naming convention can be defined at sponsor level to identify keyword, such as `Add`, `Fix`, `Remove`, `Update`, etc. The keyword can also be separated form the rest of the title using symbols such as `:` or `!` (for major or breaking changes). For instance:\n\n\n```{bash}\nAdd: TRTEMFL in adae.R\n```\n\n```{bash}\nUpdate! prim endpoint logic in efficacy (adre.R)\n```\n\n\nUsing tags that to identify the location of changes can also be an option, such as `SDTM:`, `ADAM:` or `TLF:` for instance.\n\n\n```{bash}\nTLF: create overview of AEs\n```\n\n", + "supporting": [ + "index_files" + ], + "filters": [], + "includes": {} + } +} \ No newline at end of file diff --git a/site/_freeze/site_libs/clipboard/clipboard.min.js b/site/_freeze/site_libs/clipboard/clipboard.min.js new file mode 100644 index 0000000..1103f81 --- /dev/null +++ b/site/_freeze/site_libs/clipboard/clipboard.min.js @@ -0,0 +1,7 @@ +/*! + * clipboard.js v2.0.11 + * https://clipboardjs.com/ + * + * Licensed MIT © Zeno Rocha + */ +!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.ClipboardJS=e():t.ClipboardJS=e()}(this,function(){return n={686:function(t,e,n){"use strict";n.d(e,{default:function(){return b}});var e=n(279),i=n.n(e),e=n(370),u=n.n(e),e=n(817),r=n.n(e);function c(t){try{return document.execCommand(t)}catch(t){return}}var a=function(t){t=r()(t);return c("cut"),t};function o(t,e){var n,o,t=(n=t,o="rtl"===document.documentElement.getAttribute("dir"),(t=document.createElement("textarea")).style.fontSize="12pt",t.style.border="0",t.style.padding="0",t.style.margin="0",t.style.position="absolute",t.style[o?"right":"left"]="-9999px",o=window.pageYOffset||document.documentElement.scrollTop,t.style.top="".concat(o,"px"),t.setAttribute("readonly",""),t.value=n,t);return e.container.appendChild(t),e=r()(t),c("copy"),t.remove(),e}var f=function(t){var e=10?setTimeout((function(){e(r,n,s)}),1):(t.update(),n(s))}}},"./src/filter.js":function(t){t.exports=function(t){return t.handlers.filterStart=t.handlers.filterStart||[],t.handlers.filterComplete=t.handlers.filterComplete||[],function(e){if(t.trigger("filterStart"),t.i=1,t.reset.filter(),void 0===e)t.filtered=!1;else{t.filtered=!0;for(var r=t.items,n=0,s=r.length;nv.page,a=new g(t[s],void 0,n),v.items.push(a),r.push(a)}return v.update(),r}m(t.slice(0),e)}},this.show=function(t,e){return this.i=t,this.page=e,v.update(),v},this.remove=function(t,e,r){for(var n=0,s=0,i=v.items.length;s-1&&r.splice(n,1),v},this.trigger=function(t){for(var e=v.handlers[t].length;e--;)v.handlers[t][e](v);return v},this.reset={filter:function(){for(var t=v.items,e=t.length;e--;)t[e].filtered=!1;return v},search:function(){for(var t=v.items,e=t.length;e--;)t[e].found=!1;return v}},this.update=function(){var t=v.items,e=t.length;v.visibleItems=[],v.matchingItems=[],v.templater.clear();for(var r=0;r=v.i&&v.visibleItems.lengthe},innerWindow:function(t,e,r){return t>=e-r&&t<=e+r},dotted:function(t,e,r,n,s,i,a){return this.dottedLeft(t,e,r,n,s,i)||this.dottedRight(t,e,r,n,s,i,a)},dottedLeft:function(t,e,r,n,s,i){return e==r+1&&!this.innerWindow(e,s,i)&&!this.right(e,n)},dottedRight:function(t,e,r,n,s,i,a){return!t.items[a-1].values().dotted&&(e==n&&!this.innerWindow(e,s,i)&&!this.right(e,n))}};return function(e){var n=new i(t.listContainer.id,{listClass:e.paginationClass||"pagination",item:e.item||"
  • ",valueNames:["page","dotted"],searchClass:"pagination-search-that-is-not-supposed-to-exist",sortClass:"pagination-sort-that-is-not-supposed-to-exist"});s.bind(n.listContainer,"click",(function(e){var r=e.target||e.srcElement,n=t.utils.getAttribute(r,"data-page"),s=t.utils.getAttribute(r,"data-i");s&&t.show((s-1)*n+1,n)})),t.on("updated",(function(){r(n,e)})),r(n,e)}}},"./src/parse.js":function(t,e,r){t.exports=function(t){var e=r("./src/item.js")(t),n=function(r,n){for(var s=0,i=r.length;s0?setTimeout((function(){e(r,s)}),1):(t.update(),t.trigger("parseComplete"))};return t.handlers.parseComplete=t.handlers.parseComplete||[],function(){var e=function(t){for(var e=t.childNodes,r=[],n=0,s=e.length;n]/g.exec(t)){var e=document.createElement("tbody");return e.innerHTML=t,e.firstElementChild}if(-1!==t.indexOf("<")){var r=document.createElement("div");return r.innerHTML=t,r.firstElementChild}}},a=function(e,r,n){var s=void 0,i=function(e){for(var r=0,n=t.valueNames.length;r=1;)t.list.removeChild(t.list.firstChild)},function(){var r;if("function"!=typeof t.item){if(!(r="string"==typeof t.item?-1===t.item.indexOf("<")?document.getElementById(t.item):i(t.item):s()))throw new Error("The list needs to have at least one item on init otherwise you'll have to add a template.");r=n(r,t.valueNames),e=function(){return r.cloneNode(!0)}}else e=function(e){var r=t.item(e);return i(r)}}()};t.exports=function(t){return new e(t)}},"./src/utils/classes.js":function(t,e,r){var n=r("./src/utils/index-of.js"),s=/\s+/;Object.prototype.toString;function i(t){if(!t||!t.nodeType)throw new Error("A DOM element reference is required");this.el=t,this.list=t.classList}t.exports=function(t){return new i(t)},i.prototype.add=function(t){if(this.list)return this.list.add(t),this;var e=this.array();return~n(e,t)||e.push(t),this.el.className=e.join(" "),this},i.prototype.remove=function(t){if(this.list)return this.list.remove(t),this;var e=this.array(),r=n(e,t);return~r&&e.splice(r,1),this.el.className=e.join(" "),this},i.prototype.toggle=function(t,e){return this.list?(void 0!==e?e!==this.list.toggle(t,e)&&this.list.toggle(t):this.list.toggle(t),this):(void 0!==e?e?this.add(t):this.remove(t):this.has(t)?this.remove(t):this.add(t),this)},i.prototype.array=function(){var t=(this.el.getAttribute("class")||"").replace(/^\s+|\s+$/g,"").split(s);return""===t[0]&&t.shift(),t},i.prototype.has=i.prototype.contains=function(t){return this.list?this.list.contains(t):!!~n(this.array(),t)}},"./src/utils/events.js":function(t,e,r){var n=window.addEventListener?"addEventListener":"attachEvent",s=window.removeEventListener?"removeEventListener":"detachEvent",i="addEventListener"!==n?"on":"",a=r("./src/utils/to-array.js");e.bind=function(t,e,r,s){for(var o=0,l=(t=a(t)).length;o32)return!1;var a=n,o=function(){var t,r={};for(t=0;t=p;b--){var j=o[t.charAt(b-1)];if(C[b]=0===m?(C[b+1]<<1|1)&j:(C[b+1]<<1|1)&j|(v[b+1]|v[b])<<1|1|v[b+1],C[b]&d){var x=l(m,b-1);if(x<=u){if(u=x,!((c=b-1)>a))break;p=Math.max(1,2*a-c)}}}if(l(m+1,a)>u)break;v=C}return!(c<0)}},"./src/utils/get-attribute.js":function(t){t.exports=function(t,e){var r=t.getAttribute&&t.getAttribute(e)||null;if(!r)for(var n=t.attributes,s=n.length,i=0;i=48&&t<=57}function i(t,e){for(var i=(t+="").length,a=(e+="").length,o=0,l=0;o=i&&l=a?-1:l>=a&&o=i?1:i-a}i.caseInsensitive=i.i=function(t,e){return i((""+t).toLowerCase(),(""+e).toLowerCase())},Object.defineProperties(i,{alphabet:{get:function(){return e},set:function(t){r=[];var s=0;if(e=t)for(;s { + if (categoriesLoaded) { + activateCategory(category); + setCategoryHash(category); + } +}; + +window["quarto-listing-loaded"] = () => { + // Process any existing hash + const hash = getHash(); + + if (hash) { + // If there is a category, switch to that + if (hash.category) { + activateCategory(hash.category); + } + // Paginate a specific listing + const listingIds = Object.keys(window["quarto-listings"]); + for (const listingId of listingIds) { + const page = hash[getListingPageKey(listingId)]; + if (page) { + showPage(listingId, page); + } + } + } + + const listingIds = Object.keys(window["quarto-listings"]); + for (const listingId of listingIds) { + // The actual list + const list = window["quarto-listings"][listingId]; + + // Update the handlers for pagination events + refreshPaginationHandlers(listingId); + + // Render any visible items that need it + renderVisibleProgressiveImages(list); + + // Whenever the list is updated, we also need to + // attach handlers to the new pagination elements + // and refresh any newly visible items. + list.on("updated", function () { + renderVisibleProgressiveImages(list); + setTimeout(() => refreshPaginationHandlers(listingId)); + + // Show or hide the no matching message + toggleNoMatchingMessage(list); + }); + } +}; + +window.document.addEventListener("DOMContentLoaded", function (_event) { + // Attach click handlers to categories + const categoryEls = window.document.querySelectorAll( + ".quarto-listing-category .category" + ); + + for (const categoryEl of categoryEls) { + const category = categoryEl.getAttribute("data-category"); + categoryEl.onclick = () => { + activateCategory(category); + setCategoryHash(category); + }; + } + + // Attach a click handler to the category title + // (there should be only one, but since it is a class name, handle N) + const categoryTitleEls = window.document.querySelectorAll( + ".quarto-listing-category-title" + ); + for (const categoryTitleEl of categoryTitleEls) { + categoryTitleEl.onclick = () => { + activateCategory(""); + setCategoryHash(""); + }; + } + + categoriesLoaded = true; +}); + +function toggleNoMatchingMessage(list) { + const selector = `#${list.listContainer.id} .listing-no-matching`; + const noMatchingEl = window.document.querySelector(selector); + if (noMatchingEl) { + if (list.visibleItems.length === 0) { + noMatchingEl.classList.remove("d-none"); + } else { + if (!noMatchingEl.classList.contains("d-none")) { + noMatchingEl.classList.add("d-none"); + } + } + } +} + +function setCategoryHash(category) { + setHash({ category }); +} + +function setPageHash(listingId, page) { + const currentHash = getHash() || {}; + currentHash[getListingPageKey(listingId)] = page; + setHash(currentHash); +} + +function getListingPageKey(listingId) { + return `${listingId}-page`; +} + +function refreshPaginationHandlers(listingId) { + const listingEl = window.document.getElementById(listingId); + const paginationEls = listingEl.querySelectorAll( + ".pagination li.page-item:not(.disabled) .page.page-link" + ); + for (const paginationEl of paginationEls) { + paginationEl.onclick = (sender) => { + setPageHash(listingId, sender.target.getAttribute("data-i")); + showPage(listingId, sender.target.getAttribute("data-i")); + return false; + }; + } +} + +function renderVisibleProgressiveImages(list) { + // Run through the visible items and render any progressive images + for (const item of list.visibleItems) { + const itemEl = item.elm; + if (itemEl) { + const progressiveImgs = itemEl.querySelectorAll( + `img[${kProgressiveAttr}]` + ); + for (const progressiveImg of progressiveImgs) { + const srcValue = progressiveImg.getAttribute(kProgressiveAttr); + if (srcValue) { + progressiveImg.setAttribute("src", srcValue); + } + progressiveImg.removeAttribute(kProgressiveAttr); + } + } + } +} + +function getHash() { + // Hashes are of the form + // #name:value|name1:value1|name2:value2 + const currentUrl = new URL(window.location); + const hashRaw = currentUrl.hash ? currentUrl.hash.slice(1) : undefined; + return parseHash(hashRaw); +} + +const kAnd = "&"; +const kEquals = "="; + +function parseHash(hash) { + if (!hash) { + return undefined; + } + const hasValuesStrs = hash.split(kAnd); + const hashValues = hasValuesStrs + .map((hashValueStr) => { + const vals = hashValueStr.split(kEquals); + if (vals.length === 2) { + return { name: vals[0], value: vals[1] }; + } else { + return undefined; + } + }) + .filter((value) => { + return value !== undefined; + }); + + const hashObj = {}; + hashValues.forEach((hashValue) => { + hashObj[hashValue.name] = decodeURIComponent(hashValue.value); + }); + return hashObj; +} + +function makeHash(obj) { + return Object.keys(obj) + .map((key) => { + return `${key}${kEquals}${obj[key]}`; + }) + .join(kAnd); +} + +function setHash(obj) { + const hash = makeHash(obj); + window.history.pushState(null, null, `#${hash}`); +} + +function showPage(listingId, page) { + const list = window["quarto-listings"][listingId]; + if (list) { + list.show((page - 1) * list.page + 1, list.page); + } +} + +function activateCategory(category) { + // Deactivate existing categories + const activeEls = window.document.querySelectorAll( + ".quarto-listing-category .category.active" + ); + for (const activeEl of activeEls) { + activeEl.classList.remove("active"); + } + + // Activate this category + const categoryEl = window.document.querySelector( + `.quarto-listing-category .category[data-category='${category}'` + ); + if (categoryEl) { + categoryEl.classList.add("active"); + } + + // Filter the listings to this category + filterListingCategory(category); +} + +function filterListingCategory(category) { + const listingIds = Object.keys(window["quarto-listings"]); + for (const listingId of listingIds) { + const list = window["quarto-listings"][listingId]; + if (list) { + if (category === "") { + // resets the filter + list.filter(); + } else { + // filter to this category + list.filter(function (item) { + const itemValues = item.values(); + if (itemValues.categories !== null) { + const categories = itemValues.categories.split(","); + return categories.includes(category); + } else { + return false; + } + }); + } + } + } +} diff --git a/site/posts/how-to-commit/index.qmd b/site/posts/how-to-commit/index.qmd index df5b426..fc88996 100644 --- a/site/posts/how-to-commit/index.qmd +++ b/site/posts/how-to-commit/index.qmd @@ -58,7 +58,7 @@ I think talking about `git checkout` and `git reset` here is not useful. Maybe a ### Commit one file at a time or several? -The choice depends on the context and what you want to show. +The choice depends on the context and what you want to show. Generally, each commit should be dedicated to a single purpose. If the task or feature to add is isolated to a single file, one commit message done at the end of the update can be easily readable and integrated to the history trackchange. @@ -74,3 +74,54 @@ Need feedbacks. ## How to write a good commit message +As a history tracking, a commit message should be concise and clearly explain **what** was done and **why**. + +It is important to have good commit messages because, as mentioned above, it can replace a classic track change history. The goal is to have messages that will help understanding the changes and will help during the quality control, review or audit steps. + +### Title + +The title should be very short (around 50 characters) and explain **what was done** on which file(s) (if relevant). + +Starting the title with a verb is very useful to explain what was done, for instance: + +::: note +`Add TRTEMFL in adae.R` +::: + +A naming convention can be defined at sponsor level to identify keyword, such as `Add`, `Fix`, `Remove`, `Update`, etc. The keyword can also be separated form the rest of the title using symbols such as `:` or `!` (for major or breaking changes). For instance: + +::: note +`Add: TRTEMFL in adae.R` +::: + +or + +::: note +`Update! prim endpoint logic in efficacy (adre.R)` +::: + +Using tags that to identify the location of changes can also be an option, such as `SDTM:`, `ADAM:` or `TLF:` for instance. + +::: note +`TLF: create overview of AEs` +::: + +### Detail + +The detail explains **why** the commit needed to be done, the methodological or technical context, or any relevant information that needs to understand the commit. + +It should contains, when relevant, the source (such as a new version of the statistical analysis plan, a decision taken in a meeting minutes, an email, etc), the impact (a modification on a ADaM dataset will have an impact on the TL&F describing the updated variables) or the associated logic. + +It should be informative but also concise. + +Here is an example of a commit message including a title and the body (detail): + +::: note +`Add! ANLzzFL in ADxx, ADyy, and ADzz for efficacy` + +`Implements ANLzzFL variable in ADxx, ADyy, and ADzz to identify records for inclusion in the new efficacy analysis introduced in SAP release 3.0 (part 4.5.1, [title]).` + +`This flag marks the specific records relevant to the new analysis.` + +`Impact: downstream efficacy tables and participant selection for regulatory outputs.` +::: From 90f08c3dbbfd362d93228adfb216d2d64f66d324 Mon Sep 17 00:00:00 2001 From: aassuied-ps <123543888+aassuied-ps@users.noreply.github.com> Date: Wed, 3 Sep 2025 09:13:35 +0200 Subject: [PATCH 4/6] Add conventionalcommits.org --- site/posts/how-to-commit/index.qmd | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/site/posts/how-to-commit/index.qmd b/site/posts/how-to-commit/index.qmd index fc88996..47ffee1 100644 --- a/site/posts/how-to-commit/index.qmd +++ b/site/posts/how-to-commit/index.qmd @@ -117,11 +117,17 @@ It should be informative but also concise. Here is an example of a commit message including a title and the body (detail): ::: note -`Add! ANLzzFL in ADxx, ADyy, and ADzz for efficacy` +**`Add! ANLzzFL in ADxx, ADyy, and ADzz for efficacy`** -`Implements ANLzzFL variable in ADxx, ADyy, and ADzz to identify records for inclusion in the new efficacy analysis introduced in SAP release 3.0 (part 4.5.1, [title]).` +`Implements ANLzzFL variable in ADxx, ADyy, and ADzz to identify records for inclusion in the new efficacy analysis introduced in SAP release 3.0 (part 4.5.1, [title]).` -`This flag marks the specific records relevant to the new analysis.` +`This flag marks the specific records relevant to the new analysis.` `Impact: downstream efficacy tables and participant selection for regulatory outputs.` ::: + +::: callout-tip +#### Conventional commits + +[conventionalcommits.org](https://www.conventionalcommits.org/en/v1.0.0/) gives tips and guidance for writing commit messages. +::: From bae201a450e649cf67021e2ba4f1d921fdee1370 Mon Sep 17 00:00:00 2001 From: aassuied-ps <123543888+aassuied-ps@users.noreply.github.com> Date: Wed, 1 Oct 2025 16:20:38 +0200 Subject: [PATCH 5/6] Updates after review --- site/posts/how-to-commit/index.qmd | 59 +++++++++++++++++++++++------- 1 file changed, 45 insertions(+), 14 deletions(-) diff --git a/site/posts/how-to-commit/index.qmd b/site/posts/how-to-commit/index.qmd index 47ffee1..f83ecc2 100644 --- a/site/posts/how-to-commit/index.qmd +++ b/site/posts/how-to-commit/index.qmd @@ -1,6 +1,6 @@ --- title: "How to write a good commit message" -subtitle: "Keep easy trackchanges history for your project" +subtitle: "Keep easy track changes history for your project" author: "alex" date: "2025-08-22" categories: [git, version-control, revision-history] @@ -34,7 +34,7 @@ Despite the fact that making commit is mandatory when working on a Git repositor ### Keep clear history of changes -Commonly, each program has a header that contains a *"Revision history"* part. Git commits can easily replace this part because it contains the main information of a classic revision history message (author, date and reason for change), associated to the full files comparisons, such as a before/after view. +In traditional approaches, each program has a header that contains a *"Revision history"* part. Git commits can easily replace this part because it contains the main information of a classic revision history message (author, date and reason for change), associated to the full files comparisons, such as a before/after view. All the changes of a single commit are stored in the same place. It means if you work on a single task that request to modify several programs, you can summarize the changes within one message. You do not need to open each separated files one by one to look at what was done, when, and by who. @@ -48,12 +48,6 @@ Even with several commits, you can have a clear view of all the changes when mer As Git is a version control software, and each commit is a snapshot done at a current state, it is easy to go back to a previous version of a branch using commit IDs. -::: callout-caution -#### Need feedbacks - hash - -I think talking about `git checkout` and `git reset` here is not useful. Maybe another blog post could be interesting. What do you think? -::: - ## When to commit? ### Commit one file at a time or several? @@ -66,18 +60,18 @@ In the case of a debugging task over several files, one commit message per file When a change on a program affects the behavior of other programs that also needs to be updated, one commit for all the modifications can be done. Also when you decide to modify both a program and the associated documentation. -::: callout-caution -#### Need feedbacks. - -Need feedbacks. -::: - ## How to write a good commit message As a history tracking, a commit message should be concise and clearly explain **what** was done and **why**. It is important to have good commit messages because, as mentioned above, it can replace a classic track change history. The goal is to have messages that will help understanding the changes and will help during the quality control, review or audit steps. +::: callout-tip +#### Consolidate all commits of a branch + +Even with several commits, you can have a clear view of all the changes when merging to the source branch. +::: + ### Title The title should be very short (around 50 characters) and explain **what was done** on which file(s) (if relevant). @@ -106,6 +100,12 @@ Using tags that to identify the location of changes can also be an option, such `TLF: create overview of AEs` ::: +::: callout-tip +#### Keywords and source code management platforms + +So websites such as GitHub are able to recognize some keywords such as `closes` in the title, that will automatically perform an action on the issue or branch (for instance, `closes` will close the issue). +::: + ### Detail The detail explains **why** the commit needed to be done, the methodological or technical context, or any relevant information that needs to understand the commit. @@ -114,6 +114,8 @@ It should contains, when relevant, the source (such as a new version of the stat It should be informative but also concise. +Using source code management platforms (GitHub, GitLab, BitBucket, etc) allows a direct link to issues in the title or detail of a commit (for instance `Linked to #35`) + Here is an example of a commit message including a title and the body (detail): ::: note @@ -131,3 +133,32 @@ Here is an example of a commit message including a title and the body (detail): [conventionalcommits.org](https://www.conventionalcommits.org/en/v1.0.0/) gives tips and guidance for writing commit messages. ::: + +::: callout-tip +#### Using AI to improve commits +Tools such as GitHub Copilot can help to write a good commit message by reviewing a branch and the updated done. +::: + +## Examples of bad commit messages + +### Single keyword + +A message such as `fix` with no addition or detail is too vague. It is not possible to understand directly which file has been fixed and why. + +### Too wordy title + +The following title is way too long and difficult to read easily: + +` +Update participant demographics summary dataset (ADSL) to include additional needed variables for geographical regions groups requested during the study team meeting on September 1st 2025 following the last version (1.2) of the SAP. +` + +A better way would be to have a title like this one: + +`Add ADSL.REGION1(N)` + +And a detailed description such as this one: + +`Following study team meeting (01-SEP-2025).` + +`Done as per SAP (v1.2).` From 40ffb8dc110c7260cd761126794658e9e7fc0aa5 Mon Sep 17 00:00:00 2001 From: aassuied-ps <123543888+aassuied-ps@users.noreply.github.com> Date: Thu, 2 Oct 2025 08:48:05 +0200 Subject: [PATCH 6/6] Correction on AI tool --- site/posts/how-to-commit/index.qmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/site/posts/how-to-commit/index.qmd b/site/posts/how-to-commit/index.qmd index f83ecc2..42c4dbc 100644 --- a/site/posts/how-to-commit/index.qmd +++ b/site/posts/how-to-commit/index.qmd @@ -136,7 +136,7 @@ Here is an example of a commit message including a title and the body (detail): ::: callout-tip #### Using AI to improve commits -Tools such as GitHub Copilot can help to write a good commit message by reviewing a branch and the updated done. +Tools such as GitHub Copilot can help to write a good commit message by reviewing a branch and what updates were done. ::: ## Examples of bad commit messages